Seri işlem yürütmeler ve hızlı mesaj sıraları

Neural Networks HAL 1.2 sürümünde seri yürütme kavramı açıklanmaktadır. Seri çekim yürütme işlemleri, aynı hazırlanan modelin yürütülmesi sırasında gerçekleşen (ör. bir kamera görüntüsü karelerinde çalışan veya ardışık ses kullanabilirsiniz. Seri işlem nesnesi, bir dizi seri işlem yürütmeyi kontrol etmek ve yürütmeler arasında kaynakları koruyarak yürütme işlemlerinin daha düşük olmasını sağlar yardımcı olabilir. Seri çekim nesneleri üç optimizasyon sağlar:

  1. Bir dizi yürütme işleminden önce seri işlem nesnesi oluşturulur ve nesne serbest bırakılır dizi bittiğinde. Bu nedenle, patlamanın ömrü, sürücüye, yüksek performansta kalması gerekene dair nesne ipuçları durumu.
  2. Seri işlem nesnesi, yürütmeler arasında kaynakları koruyabilir. Örneğin, sürücüsü, ilk yürütmede bir bellek nesnesini eşleyebilir ve eşlemeyi önbelleğe alabilir sonraki yürütmelerde yeniden kullanılabilmesi için seri işlem nesnesine aktarılır. Önbelleğe alınan tüm kaynaklar seri işlem yapan nesne imha edildiğinde veya NNAPI çalışma zamanı, seri çekim nesnesine kaynağın artık gerekli olmadığını bildirir.
  3. Seri çekim bir nesne, hızlı ileti sıraları (FMQ'lar) kullanarak uygulama ve sürücü işlemleri arasında iletişim kurun. Bu FMQ HIDL'yi atlayıp verileri doğrudan ortak bellekte atomik dairesel bir FIFO yoluyla başka bir süreç. İlgili içeriği oluşturmak için kullanılan tüketici süreci bir öğeyi kuyruğa çıkaracağını ve veya FMQ'nun etkinliğini bekleyerek FIFO'daki element sayısını yoklama. işareti koyun. Bu etkinlik bayrağı hızlı kullanıcı alanı karşılıklı dışlama (futex) değeri.

FMQ, müşteri memnuniyeti açısından ömür boyu garanti sürecin süreçlerin tamamlanıp tamamlanmadığını belirlemek için yerleşik bir mekanizmaya sahip değildir. ve FMQ'nun diğer ucu beklendiği gibi çalışıyor. Sonuç olarak, Yeşil Ofis’in FMQ ölürse tüketici hiç gelmeyen verileri beklerken tıkanabilir. Bir Bu sorunun çözümü, sürücünün FMQ'ları seri çekimin ne zaman sona erdiğini algılamak için daha yüksek düzeyde seri işlem nesnesi.

Seri işlem yürütmeler aynı bağımsız değişkenler üzerinde çalışır ve aynı diğer yürütme yollarıyla aynı olduğu için temel FMQ'lar aynı verileri NNAPI hizmet sürücülerinden yararlanır. Ancak FMQ'lar yalnızca veri türlerinden ibarettir. Karmaşık verilerin aktarımı, serileştirme yöntemiyle gerçekleştirilir ve iç içe yerleştirilmiş arabelleklerin (vektör türleri) doğrudan FMQ'larda seri durumdan çıkarılması ve İsteğe bağlı olarak bellek havuzu herkese açık kullanıcı adlarını aktarmak için HIDL geri çağırma nesneleri. Yapımcı isteği veya sonuç mesajlarını tüketiciye göndermelidir. sıra engelleniyorsa MessageQueue::writeBlocking kullanarak veya sıra sizi engellemiyorsa MessageQueue::write kullanarak

Seri çekim arayüzleri

Sinir Ağları HAL'sinin seri çekim arayüzleri şurada bulunabilir: hardware/interfaces/neuralnetworks/1.2/ ve aşağıda açıklanmıştır. NDK'daki seri arayüzler hakkında daha fazla bilgi için katmanı için frameworks/ml/nn/runtime/include/NeuralNetworks.h.

türler.hal

types.hal FMQ üzerinden gönderilen veri türünü tanımlar.

  • FmqRequestDatum: Request yürütmenin serileştirilmiş temsilinin tek bir öğesi nesne ve hızlı mesaj üzerinden gönderilen MeasureTiming değeri sıra.
  • FmqResultDatum: Döndürülen değerlerin serileştirilmiş temsilinin tek bir öğesi (ErrorStatus, OutputShapes ve Timing) hızlı ileti kuyruğuna geri döndürülür.

IBurstContext.hal

IBurstContext.hal Nöral Ağlar hizmetinde bulunan HIDL arayüz nesnesini tanımlar.

  • IBurstContext: Bir seri çekimin kaynaklarını yönetmek için kullanılan bağlam nesnesi.

IBurstCallback.hal

IBurstCallback.hal Nöral Ağlar tarafından oluşturulan bir geri çağırma için HIDL arayüz nesnesini tanımlar ve hidl_memory değerini almak için Nöral Ağlar hizmeti tarafından kullanılır nesne tanımlayıcılarını kullanır.

  • IBurstCallback: Bir hizmet tarafından bellek nesnelerini almak için kullanılan geri çağırma nesnesi.

IPreparedModel.hal

IPreparedModel.hal işlevi, HAL 1.2'de bir IBurstContext nesne oluşturma yöntemiyle modelimiz Gemini Nano.

  • configureExecutionBurst: Hazır bir projede birden fazla çıkarım yürütmek için kullanılan bir seri işlem nesnesini yapılandırır hızlı bir şekilde modeller.

Bir sürücüde seri yürütme işlemlerini destekleme

Bir HIDL NNAPI hizmetinde seri çekim nesneleri desteklemenin en basit yolu ::android::nn::ExecutionBurstServer::create seri çekim yardımcı programı bulundu ExecutionBurstServer.h libneuralnetworks_common ve libneuralnetworks_util olarak paketlenir olması gerekir. Bu fabrika işlevinde iki aşırı yükleme var:

  • Bir aşırı yükleme, bir IPreparedModel nesnesine işaretçiyi kabul ediyor. Bu yardımcı program işlevi, executeSynchronously yöntemini IPreparedModel nesnesini ifade eder.
  • Bir aşırı yükleme, özelleştirilebilir IBurstExecutorWithCache nesnesi kabul ediyor Bu erişim, izin verilen kaynakları (ör. hidl_memory eşlemeleri) önbelleğe almak için birçok yürütmede kalıcı olur.

Her aşırı yükleme, bir IBurstContext nesnesi döndürür (bu, patlamayı temsil eder) nesnesi) bulunmalıdır. Bu mesaj dizisi requestChannel FMQ'dan istek alır, çıkarımı yapar, ardından sonuçları resultChannel FMQ aracılığıyla döndürür. Bu ileti dizisi ve tüm diğer IBurstContext nesnesinde bulunan kaynaklar otomatik olarak serbest bırakılır Seri çekimin istemcisinin IBurstContext referansını kaybetmesi.

Alternatif olarak, IBurstContext API'sini kullanan kendi uygulamanızı oluşturabilirsiniz requestChannel üzerinden nasıl mesaj gönderip alacağını biliyor ve IPreparedModel::configureExecutionBurst adresine resultChannel FMQ gönderildi.

Seri çekim yardımcı program işlevleri şurada bulunur: ExecutionBurstServer.h.

/**
 * Create automated context to manage FMQ-based executions.
 *
 * This function is intended to be used by a service to automatically:
 * 1) Receive data from a provided FMQ
 * 2) Execute a model with the given information
 * 3) Send the result to the created FMQ
 *
 * @param callback Callback used to retrieve memories corresponding to
 *     unrecognized slots.
 * @param requestChannel Input FMQ channel through which the client passes the
 *     request to the service.
 * @param resultChannel Output FMQ channel from which the client can retrieve
 *     the result of the execution.
 * @param executorWithCache Object which maintains a local cache of the
 *     memory pools and executes using the cached memory pools.
 * @result IBurstContext Handle to the burst context.
 */
static sp<ExecutionBurstServer> create(
        const sp<IBurstCallback>& callback, const FmqRequestDescriptor& requestChannel,
        const FmqResultDescriptor& resultChannel,
        std::shared_ptr<IBurstExecutorWithCache> executorWithCache);

/**
 * Create automated context to manage FMQ-based executions.
 *
 * This function is intended to be used by a service to automatically:
 * 1) Receive data from a provided FMQ
 * 2) Execute a model with the given information
 * 3) Send the result to the created FMQ
 *
 * @param callback Callback used to retrieve memories corresponding to
 *     unrecognized slots.
 * @param requestChannel Input FMQ channel through which the client passes the
 *     request to the service.
 * @param resultChannel Output FMQ channel from which the client can retrieve
 *     the result of the execution.
 * @param preparedModel PreparedModel that the burst object was created from.
 *     IPreparedModel::executeSynchronously will be used to perform the
 *     execution.
 * @result IBurstContext Handle to the burst context.
 */
  static sp<ExecutionBurstServer> create(const sp<IBurstCallback>& callback,
                                         const FmqRequestDescriptor& requestChannel,
                                         const FmqResultDescriptor& resultChannel,
                                         IPreparedModel* preparedModel);

Aşağıda, Nöral Ağları örnek sürücüsü frameworks/ml/nn/driver/sample/SampleDriver.cpp.

Return<void> SamplePreparedModel::configureExecutionBurst(
        const sp<V1_2::IBurstCallback>& callback,
        const MQDescriptorSync<V1_2::FmqRequestDatum>& requestChannel,
        const MQDescriptorSync<V1_2::FmqResultDatum>& resultChannel,
        configureExecutionBurst_cb cb) {
    NNTRACE_FULL(NNTRACE_LAYER_DRIVER, NNTRACE_PHASE_EXECUTION,
                 "SampleDriver::configureExecutionBurst");
    // Alternatively, the burst could be configured via:
    // const sp<V1_2::IBurstContext> burst =
    //         ExecutionBurstServer::create(callback, requestChannel,
    //                                      resultChannel, this);
    //
    // However, this alternative representation does not include a memory map
    // caching optimization, and adds overhead.
    const std::shared_ptr<BurstExecutorWithCache> executorWithCache =
            std::make_shared<BurstExecutorWithCache>(mModel, mDriver, mPoolInfos);
    const sp<V1_2::IBurstContext> burst = ExecutionBurstServer::create(
            callback, requestChannel, resultChannel, executorWithCache);
    if (burst == nullptr) {
        cb(ErrorStatus::GENERAL_FAILURE, {});
    } else {
        cb(ErrorStatus::NONE, burst);
    }
    return Void();
}