Nöral Ağlar HAL 1.2, toplu yürütme kavramını kullanıma sunar. Seri yürütmeler, aynı hazırlanmış modelin hızlı bir şekilde art arda yürütülmesidir (ör. kamera yakalama kareleri veya art arda ses örnekleri üzerinde çalışanlar). Patlama nesnesi, bir dizi patlama yürütme işlemini kontrol etmek ve yürütmeler arasında kaynakları korumak için kullanılır. Böylece yürütmelerin daha düşük ek maliyete sahip olması sağlanır. Patlama 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 nesnesinin ömrü, sürücüye ne kadar süre boyunca yüksek performanslı durumda kalması gerektiğini belirtir.
- Patlama nesnesi, yürütmeler arasında kaynakları koruyabilir. Örneğin, bir sürücü ilk yürütmede bir bellek nesnesini eşleyebilir ve sonraki yürütmelerde yeniden kullanmak için eşlemeyi patlama nesnesinde önbelleğe alabilir. Önbelleğe alınan tüm kaynaklar, patlama nesnesi yok edildiğinde veya NNAPI çalışma zamanı, patlama nesnesine kaynağın artık gerekli olmadığını bildirdiğinde serbest bırakılabilir.
- Patlama nesnesi, uygulama ile sürücü işlemleri arasında iletişim kurmak için hızlı mesaj sıraları (FMQ'ler) kullanır. FMQ, HIDL'yi atladığı ve verileri paylaşılan bellekteki atomik dairesel FIFO aracılığıyla doğrudan başka bir sürece ilettiği için bu durum gecikmeyi azaltabilir. Tüketici işlemi, FIFO'daki öğe sayısını sorgulayarak veya üretici tarafından sinyal verilen FMQ etkinlik işaretini bekleyerek bir öğeyi sıra dışı bırakmayı ve işlemeye başlamayı bilir. Bu etkinlik işareti, hızlı bir kullanıcı alanı mutex'idir (futex).
FMQ, işlemler genelinde ömür boyu garanti sunmayan ve FMQ'nin diğer ucundaki işlemin beklendiği gibi çalışıp çalışmadığını belirlemek için yerleşik bir mekanizmaya sahip olmayan düşük düzey bir veri yapısıdır. Sonuç olarak, FMQ için üretici sonlandırılırsa tüketici, hiçbir zaman gelmeyecek verileri beklemeye devam edebilir. Bu sorunun bir çözümü, sürücünün FMQ'leri, toplu yürütmenin ne zaman sona erdiğini algılamak için daha üst düzey toplu nesneyle ilişkilendirmesidir.
Art arda yürütme işlemleri aynı bağımsız değişkenlerle çalışır ve diğer yürütme yollarıyla aynı sonuçları döndürür. Bu nedenle, temel FMQ'ler NNAPI hizmet sürücülerine ve bu sürücülerden aynı verileri iletmelidir. Ancak FMQ'ler yalnızca eski veri türlerini aktarabilir. Karmaşık verilerin aktarımı, doğrudan FMQ'lerde iç içe yerleştirilmiş arabelleklerin (vektor türleri) serileştirilmesi ve seri dışı bırakılması 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'nin üretici tarafı, istek veya sonuç mesajlarını tüketiciye atomik olarak göndermelidir. Sıralı liste engelleniyorsa MessageQueue::writeBlocking
, engellenmiyorsa MessageQueue::write
kullanılmalıdır.
Seri çekim arayüzleri
Nöral Ağlar HAL'i için burst arayüzleri hardware/interfaces/neuralnetworks/1.2/
bölümünde bulunur ve aşağıda açıklanmıştır. NDK katmanındaki patlama 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
: Hızlı mesaj kuyruğunda gönderilen bir yürütmeRequest
nesnesinin veMeasureTiming
değerinin serileştirilmiş temsilinin tek bir öğesi.FmqResultDatum
: Bir yürütmeden döndürülen değerlerin (ErrorStatus
,OutputShapes
veTiming
) hızlı mesaj kuyruğu aracılığıyla döndürülen serileştirilmiş temsilinin tek bir öğesi.
IBurstContext.hal
IBurstContext.hal
Nöral Ağlar hizmetinde bulunan HIDL arayüz nesnesini tanımlar.
IBurstContext
: Bir artışı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 hizmet tarafından bellek nesnelerini almak için kullanılan 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ırlanmış bir model üzerinde hızlı bir şekilde art arda birden fazla çıkarım yürütmek için kullanılan bir burst nesnesi yapılandırır.
Sürücüler için toplu yürütme desteği
HIDL NNAPI hizmetinde toplu nesneleri desteklemenin en basit yolu, ExecutionBurstServer.h
içinde bulunan ve libneuralnetworks_common
ile libneuralnetworks_util
statik kitaplıklarında paketlenmiş toplu yardımcı işlevi ::android::nn::ExecutionBurstServer::create
'ü kullanmaktır. Bu fabrika işlevinin iki aşırı yüklemesi vardır:
- Bir aşırı yükleme,
IPreparedModel
nesnesine işaretçi kabul eder. Bu yardımcı işlev, modeli yürütmek içinIPreparedModel
nesnesindeexecuteSynchronously
yöntemini kullanır. - Bir aşırı yükleme, birden fazla yürütme boyunca kalıcı olan kaynakları (
hidl_memory
eşlemeleri gibi) önbelleğe almak için kullanılabilen özelleştirilebilir birIBurstExecutorWithCache
nesnesi kabul eder.
Her aşırı yükleme, kendi özel dinleyici iş parçacığını içeren ve yöneten bir IBurstContext
nesnesi (patlama nesnesini temsil eder) döndürür. Bu iş parçacığı, requestChannel
FMQ'den istek alır, çıkarım yapar ve sonuçları resultChannel
FMQ üzerinden döndürür. Bu mesaj dizisi ve IBurstContext
nesnesinde bulunan diğer tüm kaynaklar, burst'in müşterisi IBurstContext
referansını kaybettiğinde otomatik olarak serbest bırakılır.
Alternatif olarak, IPreparedModel::configureExecutionBurst
'a iletilen requestChannel
ve resultChannel
FMQ'leri üzerinden mesaj gönderip almayı anlayan kendi IBurstContext
uygulamanızı oluşturabilirsiniz.
Seri çekim hizmet 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();
}