Nöral Ağlar HAL 1.2, patlama yürütmeleri kavramını sunar. Patlama yürütmeleri, aynı hazırlanmış modelin hızlı bir şekilde gerçekleşen bir dizi yürütmesidir. Örneğin, kamera yakalama kareleri veya ardışık ses örnekleri üzerinde çalışanlar. Patlama nesnesi, bir dizi patlama yürütmesini kontrol etmek ve yürütmeler arasında kaynakları korumak için kullanılır. Böylece yürütmeler daha düşük ek yüke sahip olabilir. Patlatma nesneleri üç optimizasyonu etkinleştirir:
- Patlama nesnesi, bir yürütme dizisinden önce oluşturulur ve dizi sona erdiğinde serbest bırakılır. Bu nedenle, patlama nesnesi ömrü, sürücüye ne kadar süreyle yüksek performans durumunda kalması gerektiğini bildirir.
- Patlama nesnesi, yürütmeler arasındaki kaynakları koruyabilir. Örneğin, bir sürücü ilk yürütmede bir bellek nesnesini eşleyebilir ve sonraki yürütmelerde yeniden kullanmak üzere patlama nesnesinde eşlemeyi önbelleğe alabilir. Patlama nesnesi yok edildiğinde veya NNAPI çalışma zamanı, patlama nesnesine kaynağın artık gerekli olmadığını bildirdiğinde önbelleğe alınmış tüm kaynaklar serbest bırakılabilir.
- Patlama nesnesi, uygulama ve sürücü işlemleri arasında iletişim kurmak için hızlı mesaj kuyruklarını (FMQ) kullanır. FMQ, HIDL'yi atlayıp verileri paylaşılan bellekteki atomik dairesel FIFO aracılığıyla doğrudan başka bir işleme ilettiği için gecikme süresini azaltabilir. Tüketici süreci, FIFO'daki öğe sayısını yoklayarak veya üretici tarafından sinyal verilen FMQ'nun etkinlik işaretini bekleyerek bir öğeyi kuyruktan çıkarma ve işlemeye başlama konusunda bilgi sahibidir. Bu etkinlik işareti, hızlı bir kullanıcı alanı karşılıklı dışlama kilididir (futex).
FMQ, süreçler arasında kullanım ömrü garantisi sunmayan ve FMQ'nun diğer ucundaki sürecin beklendiği gibi çalışıp çalışmadığını belirlemek için yerleşik bir mekanizmaya sahip olmayan düşük seviyeli bir veri yapısıdır. Dolayısıyla, FMQ'nun üreticisi ölürse tüketici, hiçbir zaman gelmeyecek verileri beklemek zorunda kalabilir. Bu sorunun bir çözümü, sürücünün FMQ'ları daha üst düzey burst nesnesiyle ilişkilendirerek burst yürütmenin ne zaman sona erdiğini algılamasıdır.
Toplu yürütmeler aynı bağımsız değişkenler üzerinde çalıştığından ve diğer yürütme yollarıyla aynı sonuçları döndürdüğünden, temel FMQ'lar aynı verileri NNAPI hizmet sürücülerine ve sürücülerden geçirmelidir. Ancak FMQ'lar yalnızca basit veri türlerini aktarabilir. Karmaşık verilerin aktarımı, iç içe yerleştirilmiş arabelleklerin (vektör türleri) doğrudan FMQ'larda serileştirilmesi ve seri durumdan çıkarılmasıyla ve bellek havuzu tutamaçlarını isteğe bağlı olarak aktarmak için HIDL geri çağırma nesnelerinin kullanılmasıyla gerçekleştirilir. FMQ'nun üretici tarafı, istek veya sonuç mesajlarını, kuyruk engelliyorsa MessageQueue::writeBlocking kullanarak, engellemiyorsa MessageQueue::write kullanarak tüketiciye atomik olarak göndermelidir.
Seri arayüzler
Neural Networks HAL'nin patlama arayüzleri hardware/interfaces/neuralnetworks/1.2/ içinde bulunur ve aşağıda açıklanmıştır. NDK katmanındaki burst arayüzleri hakkında daha fazla bilgi için frameworks/ml/nn/runtime/include/NeuralNetworks.h bölümüne bakın.
types.hal
types.hal
FMQ üzerinden gönderilen veri türünü tanımlar.
FmqRequestDatum: Bir yürütmeRequestnesnesinin ve hızlı mesaj kuyruğunda gönderilen birMeasureTimingdeğerinin serileştirilmiş gösteriminin tek bir öğesi.FmqResultDatum: Hızlı mesaj sırasıyla döndürülen bir yürütmeden (ErrorStatus,OutputShapesveTiming) döndürülen değerlerin serileştirilmiş gösteriminin tek bir öğesi.
IBurstContext.hal
IBurstContext.hal
Neural Networks hizmetinde bulunan HIDL arayüz nesnesini tanımlar.
IBurstContext: Patlamanın kaynaklarını yönetmek için kullanılan bağlam nesnesi.
IBurstCallback.hal
IBurstCallback.hal
Neural Networks çalışma zamanı tarafından oluşturulan bir geri çağırma için HIDL arayüz nesnesini tanımlar ve Neural Networks hizmeti tarafından yuva tanımlayıcılarına karşılık gelen hidl_memory
nesnelerini almak için kullanılır.
- IBurstCallback: Bir hizmetin bellek nesnelerini almak için kullandığı geri çağırma nesnesi.
IPreparedModel.hal
IPreparedModel.hal
HAL 1.2'de, hazırlanmış bir modelden IBurstContext nesnesi oluşturma yöntemiyle genişletilmiştir.
configureExecutionBurst: Hazırlanan bir modelde hızlı bir şekilde birden fazla çıkarım yürütmek için kullanılan bir patlama nesnesi yapılandırır.
Sürücüde toplu yürütmeleri destekleme
HIDL NNAPI hizmetinde seri işlem nesnelerini desteklemenin en basit yolu, ::android::nn::ExecutionBurstServer::create seri işlem hizmet işlevini kullanmaktır. Bu işlev, ExecutionBurstServer.h içinde bulunur ve libneuralnetworks_common ile libneuralnetworks_util statik kitaplıklarında paketlenir. Bu fabrika işlevinin iki aşırı yüklemesi vardır:
- Bir aşırı yükleme,
IPreparedModelnesnesine yönelik bir işaretçi kabul eder. Bu yardımcı işlev, modeli yürütmek içinIPreparedModelnesnesindeexecuteSynchronouslyyöntemini kullanır. - Bir aşırı yükleme, özelleştirilebilir bir
IBurstExecutorWithCachenesnesini kabul eder. Bu nesne, birden fazla yürütme boyunca kalıcı olan kaynakları (ör.hidl_memoryeşlemeleri) önbelleğe almak için kullanılabilir.
Her aşırı yükleme, kendi özel dinleyici iş parçacığını içeren ve yöneten bir IBurstContext nesnesi (burst nesnesini temsil eder) döndürür. Bu iş parçacığı, requestChannel FMQ'dan istek alır, çıkarım işlemini gerçekleştirir ve sonuçları resultChannel FMQ üzerinden döndürür. Bu iş parçacığı ve IBurstContext nesnesinde bulunan diğer tüm kaynaklar, patlamanın istemcisi IBurstContext ile olan referansını kaybettiğinde otomatik olarak serbest bırakılır.
Alternatif olarak, IBurstContext için kendi uygulamanızı oluşturabilirsiniz. Bu uygulama, requestChannel ve IPreparedModel::configureExecutionBurst'a iletilen resultChannel FMQ'lar üzerinden nasıl mesaj gönderip alacağını anlar.
Patlatma yardımcı işlevleri ExecutionBurstServer.h bölümünde bulunur.
/**
* 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, frameworks/ml/nn/driver/sample/SampleDriver.cpp adresindeki Neural Networks örnek sürücüsünde bulunan bir burst arayüzünün referans uygulaması verilmiştir.
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();
}