Neural Networks HAL 1.2, toplu yürütme 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. Bu sayede 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 ipuçlarının ömrü, sürücüye ne kadar süreyle yüksek performans durumunda kalması gerektiğini gösterir.
- 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ü süreçleri arasında iletişim kurmak için hızlı mesaj kuyruklarını (FMQ) kullanır. Bu, FMQ'nun HIDL'yi atlayıp verileri paylaşılan bellekteki atomik dairesel FIFO aracılığıyla doğrudan başka bir işleme iletmesi nedeniyle gecikmeyi azaltabilir. Tüketici süreci, FIFO'daki öğe sayısını yoklayarak veya üretici tarafından sinyali 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ı gerektiğinde aktarmak için HIDL geri çağırma nesnelerinin kullanılmasıyla gerçekleştirilir. FMQ'nun üretici tarafı, istek veya sonuç mesajlarını tüketiciye atomik olarak göndermelidir. Bu işlem, kuyruk engelliyorsa MessageQueue::writeBlocking
kullanılarak, engellemiyorsa MessageQueue::write
kullanılarak yapılmalıdır.
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
başlıklı makaleye göz atın.
types.hal
types.hal
FMQ üzerinden gönderilen veri türünü tanımlar.
FmqRequestDatum
: BirRequest
yürütme nesnesinin ve hızlı mesaj kuyruğuna gönderilen birMeasureTiming
değerinin serileştirilmiş gösteriminin tek bir öğesi.FmqResultDatum
: Yürütmeden (ErrorStatus
,OutputShapes
veTiming
) döndürülen değerlerin seri hale getirilmiş gösteriminin tek bir öğesidir. Bu öğe, hızlı mesaj sırası üzerinden döndürülür.
IBurstContext.hal
IBurstContext.hal
Neural Networks hizmetinde bulunan HIDL arayüz nesnesini tanımlar.
IBurstContext
: Bir 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ütme desteği
HIDL NNAPI hizmetinde patlama nesnelerini desteklemenin en basit yolu, ::android::nn::ExecutionBurstServer::create
patlama yardımcı 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,
IPreparedModel
nesnesinin işaretçisini kabul eder. Bu yardımcı işlev, modeli yürütmek içinIPreparedModel
nesnesindeexecuteSynchronously
yöntemini kullanır. - Bir aşırı yükleme, özelleştirilebilir bir
IBurstExecutorWithCache
nesnesini kabul eder. Bu nesne, birden fazla yürütme boyunca kalıcı olan kaynakları (ör.hidl_memory
eş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 (bu nesne, patlama 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
referansını kaybettiğinde otomatik olarak serbest bırakılır.
Alternatif olarak, IBurstContext
'nın kendi uygulamanızı oluşturabilirsiniz. Bu uygulama, requestChannel
üzerinden ve IPreparedModel::configureExecutionBurst
'a iletilen resultChannel
FMQ'lar aracılığıyla mesaj gönderme ve alma işlemlerini anlar.
Seri çekim 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();
}