विक्रेता एक्सटेंशन

एंड्रॉइड 10 में पेश किए गए न्यूरल नेटवर्क एपीआई (एनएनपीआई) विक्रेता एक्सटेंशन, विक्रेता-परिभाषित संचालन और डेटा प्रकारों का संग्रह हैं। एनएन एचएएल 1.2 या उच्चतर चलाने वाले उपकरणों पर, ड्राइवर संबंधित विक्रेता एक्सटेंशन का समर्थन करके कस्टम हार्डवेयर-त्वरित संचालन प्रदान कर सकते हैं। विक्रेता एक्सटेंशन मौजूदा परिचालन के व्यवहार को संशोधित नहीं करते हैं।

विक्रेता एक्सटेंशन ओईएम ऑपरेशन और डेटा प्रकारों के लिए अधिक संरचित विकल्प प्रदान करते हैं, जिन्हें एंड्रॉइड 10 में हटा दिया गया था। अधिक जानकारी के लिए, ओईएम ऑपरेशन और डेटा प्रकार देखें।

एक्सटेंशन उपयोग की अनुमति सूची

विक्रेता एक्सटेंशन का उपयोग केवल /product , /vendor , /odm , और /data विभाजन पर स्पष्ट रूप से निर्दिष्ट एंड्रॉइड ऐप्स और मूल बायनेरिज़ द्वारा किया जा सकता है। /system विभाजन पर स्थित ऐप्स और मूल बायनेरिज़ विक्रेता एक्सटेंशन का उपयोग नहीं कर सकते हैं।

एनएनएपीआई विक्रेता एक्सटेंशन का उपयोग करने की अनुमति वाले एंड्रॉइड ऐप्स और बायनेरिज़ की एक सूची /vendor/etc/nnapi_extensions_app_allowlist में संग्रहीत है। फ़ाइल की प्रत्येक पंक्ति में एक नई प्रविष्टि होती है। एक प्रविष्टि एक मूल बाइनरी पथ हो सकती है जिसके पहले एक स्लैश (/) लगा होता है, उदाहरण के लिए, /data/foo , या एंड्रॉइड ऐप पैकेज का नाम, उदाहरण के लिए, com.foo.bar

अनुमति सूची एनएनएपीआई रनटाइम साझा लाइब्रेरी से लागू की गई है। यह लाइब्रेरी आकस्मिक उपयोग से बचाती है, लेकिन सीधे एनएनएपीआई ड्राइवर एचएएल इंटरफ़ेस का उपयोग करके किसी ऐप द्वारा जानबूझकर की गई धोखाधड़ी से नहीं।

विक्रेता विस्तार परिभाषा

विक्रेता एक्सटेंशन परिभाषा के साथ एक हेडर फ़ाइल बनाता है और उसका रखरखाव करता है। एक्सटेंशन परिभाषा का एक पूरा उदाहरण example/fibonacci/FibonacciExtension.h में पाया जा सकता है।

प्रत्येक एक्सटेंशन का एक अद्वितीय नाम होना चाहिए जो विक्रेता के रिवर्स डोमेन नाम से शुरू होता है।

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

नाम संचालन और डेटा प्रकारों के लिए नामस्थान के रूप में कार्य करता है। विक्रेता एक्सटेंशन के बीच अंतर करने के लिए एनएनएपीआई इस नाम का उपयोग करता है।

संचालन और डेटा प्रकार 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;

एनएनएपीआई क्लाइंट में एक्सटेंशन का उपयोग करें

runtime/include/NeuralNetworksExtensions.h (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 में देखें। उपसर्ग से एक्सटेंशन नाम तक मैपिंग किसी दिए गए मॉडल के लिए एक-से-एक पत्राचार (आक्षेप) है। विभिन्न उपसर्ग मान विभिन्न मॉडलों में समान एक्सटेंशन नाम के अनुरूप हो सकते हैं।

ड्राइवर को एक्सटेंशन ऑपरेशंस और डेटा प्रकारों को मान्य करना होगा क्योंकि एनएनएपीआई रनटाइम विशेष एक्सटेंशन ऑपरेशंस और डेटा प्रकारों को मान्य नहीं कर सकता है।

एक्सटेंशन ऑपरेंड में operand.extraParams.extension में संबद्ध डेटा हो सकता है, जिसे रनटाइम मनमाने आकार के कच्चे डेटा ब्लॉब के रूप में मानता है।

OEM संचालन और डेटा प्रकार

एनएनएपीआई में डिवाइस निर्माताओं को कस्टम, ड्राइवर-विशिष्ट कार्यक्षमता प्रदान करने की अनुमति देने के लिए एक ओईएम ऑपरेशन और ओईएम डेटा प्रकार हैं। ये ऑपरेशन और डेटा प्रकार केवल OEM अनुप्रयोगों द्वारा उपयोग किए जाते हैं। ओईएम ऑपरेशन और डेटा प्रकार के शब्दार्थ ओईएम-विशिष्ट हैं और किसी भी समय बदल सकते हैं। ओईएम ऑपरेशन और डेटा प्रकार को OperationType::OEM_OPERATION , OperandType::OEM और OperandType::TENSOR_OEM_BYTE का उपयोग करके एन्कोड किया गया है।