Bu sayfada, sürücü ile çerçeve arasında etkili bir şekilde operatör arabelleklerini iletmek için kullanılan veri yapıları ve yöntemler açıklanmaktadır.
Çerçeve, model derleme sırasında sürücüye sabit operatörlerin değerlerini sağlar. Sabit operatörün kullanım süresine bağlı olarak değerleri bir HIDL vektöründe veya paylaşılan bellek havuzunda bulunur.
- Ömür
CONSTANT_COPY
ise değerler, model yapısınınoperandValues
alanında bulunur. HIDL vektöründeki değerler, işlemler arası iletişim (IPC) sırasında kopyalandığından bu vektör genellikle yalnızca skaler operatörler (ör.ADD
'teki etkinleştirme skaleri) ve küçük tenör parametreleri (ör.RESHAPE
'teki şekil tenörü) gibi az miktarda veri tutmak için kullanılır. - Ömür
CONSTANT_REFERENCE
ise değerler, model yapısınınpools
alanında bulunur. Ham değerlerin kopyalanmak yerine IPC sırasında yalnızca paylaşılan bellek havuzlarının tutamaçlarının kopyalanması Bu nedenle, paylaşılan bellek havuzlarını kullanarak büyük miktarda veri (ör. toplamalardaki ağırlık parametreleri) tutmak, HIDL vektörlerini kullanmaktan daha verimlidir.
Çerçeve, model yürütme sırasında sürücüye giriş ve çıkış operatörlerinin arabelleklerini sağlar. HIDL vektöründe gönderilebilecek derleme zamanı sabitlerinin aksine, bir yürütmenin giriş ve çıkış verileri her zaman bir bellek havuzu koleksiyonu aracılığıyla iletilir.
hidl_memory
HIDL veri türü, haritalanmamış bir paylaşılan bellek havuzunu temsil etmek için hem derleme hem de yürütme aşamasında kullanılır. Sürücü, hidl_memory
veri türünün adına göre kullanılabilir hale getirmek için belleği uygun şekilde eşlemelidir.
Desteklenen bellek adları şunlardır:
ashmem
: Android paylaşılan anı. Daha fazla bilgi için bellek bölümüne bakın.mmap_fd
:mmap
aracılığıyla dosya tanımlayıcısıyla desteklenen paylaşılan bellek.hardware_buffer_blob
:AHARDWARE_BUFFER_FORMAT_BLOB
biçiminde bir AHardwareBuffer tarafından desteklenen paylaşılan bellek. Neural Networks (NN) HAL 1.2'den itibaren kullanılabilir. Daha fazla bilgi için AHardwareBuffer başlıklı makaleyi inceleyin.hardware_buffer
:AHARDWARE_BUFFER_FORMAT_BLOB
biçimini kullanmayan genel bir AHardwareBuffer tarafından desteklenen paylaşılan bellek. BLOB olmayan moddaki donanım arabelleği yalnızca model yürütmede desteklenir.NN HAL 1.2'den itibaren kullanılabilir. Daha fazla bilgi için AHardwareBuffer başlıklı makaleyi inceleyin.
NN HAL 1.3'ten itibaren NNAPI, sürücü tarafından yönetilen tamponlar için ayırıcı arayüzleri sağlayan bellek alanlarını destekler. Sürücü tarafından yönetilen arabellekler, yürütme girişleri veya çıkışları olarak da kullanılabilir. Ayrıntılı bilgi için Bellek alanları başlıklı makaleyi inceleyin.
NNAPI sürücüleri, ashmem
ve mmap_fd
bellek adlarının eşlenmesini desteklemelidir. NN HAL 1.3'ten itibaren sürücüler hardware_buffer_blob
eşlemesini de desteklemelidir. Genel BLOB dışı mod hardware_buffer
ve bellek alanları için destek isteğe bağlıdır.
AHardwareBuffer
AHardwareBuffer, bir Gralloc arabelleğini sarmalayan bir tür paylaşılan bellektir. Android 10'da Neural Networks API (NNAPI), AHardwareBuffer'ın kullanılmasını destekler. Bu sayede sürücü, verileri kopyalamadan yürütme yapabilir. Bu da uygulamaların performansını ve güç tüketimini iyileştirir. Örneğin, bir kamera HAL yığını, kamera NDK ve medya NDK API'leri tarafından oluşturulan AHardwareBuffer tutamaçlarını kullanarak makine öğrenimi iş yükleri için AHardwareBuffer nesnelerini NNAPI'ye iletebilir. Daha fazla bilgi için ANeuralNetworksMemory_createFromAHardwareBuffer
başlıklı makaleyi inceleyin.
NNAPI'de kullanılan AHardwareBuffer nesneleri, hardware_buffer
veya hardware_buffer_blob
adlı bir hidl_memory
yapısı aracılığıyla sürücüye aktarılır.
hidl_memory
struct hardware_buffer_blob
, yalnızca AHARDWAREBUFFER_FORMAT_BLOB
biçimindeki AHardwareBuffer nesnelerini temsil eder.
Çerçeve tarafından gerekli olan bilgiler, hidl_memory
yapısının hidl_handle
alanında kodlanır. hidl_handle
alanı, AHardwareBuffer veya Gralloc arabelleği ile ilgili gerekli tüm meta verileri kodlayan native_handle
alanını sarar.
Sürücü, sağlanan hidl_handle
alanının kodunu doğru şekilde çözmeli ve hidl_handle
tarafından açıklanan belleğe erişmelidir. getSupportedOperations_1_2
, getSupportedOperations_1_1
veya getSupportedOperations
yöntemi çağrıldığında sürücü, sağlanan hidl_handle
değerinin kodunu çözüp çözemeyeceğini ve hidl_handle
tarafından açıklanan belleğe erişip erişemeyeceğini algılamalıdır. Sabit bir operatör için kullanılan hidl_handle
alanı desteklenmiyorsa model hazırlama işlemi başarısız olur. Yürütmenin giriş veya çıkış operandı için kullanılan hidl_handle
alanı desteklenmiyorsa yürütme başarısız olur. Model hazırlama veya yürütme başarısız olursa sürücünün GENERAL_FAILURE
hata kodu döndürmesi önerilir.
Anı alanları
Android 11 veya sonraki sürümleri çalıştıran cihazlarda NNAPI, sürücü tarafından yönetilen arabellekler için ayırıcı arayüzleri sağlayan bellek alanlarını destekler. Bu sayede, cihazın yerel bellekleri yürütmeler arasında aktarılabilir. Böylece aynı sürücüdeki art arda yürütmeler arasında gereksiz veri kopyalama ve dönüştürme işlemleri engellenir. Bu akış Şekil 1'de gösterilmektedir.
Şekil 1. Bellek alanlarını kullanarak veri akışını arabelleğe alma
Bellek alanı özelliği, çoğunlukla sürücüye dahil olan ve istemci tarafında sık sık erişilmesi gerekmeyen tenzorlar için tasarlanmıştır. Bu tür tensörlere örnek olarak sıra modellerindeki durum tensörleri verilebilir. İstemci tarafında sık sık CPU erişimi gerektiren tenzorlar için paylaşılan bellek havuzları kullanmak tercih edilir.
Bellek alanı özelliğini desteklemek için çerçevenin sürücü tarafından yönetilen arabellek ayırma isteğinde bulunmasına izin vermek üzere IDevice::allocate
uygulayın. Framework, tahsis sırasında arabellek için aşağıdaki özellikleri ve kullanım kalıplarını sağlar:
BufferDesc
, arabelleğin gerekli özelliklerini açıklar.BufferRole
, hazırlanmış bir modelin girişi veya çıkışı olarak arabelleğin olası kullanım şeklini tanımlar. Arabellek ayırma sırasında birden fazla rol belirtilebilir ve ayrılan arabellek yalnızca belirtilen rollerde kullanılabilir.
Ayrılan arabellek sürücü içindedir. Sürücü, herhangi bir arabellek konumunu veya veri düzenini seçebilir. Arabellek başarıyla ayrıldığında sürücünün istemcisi, döndürülen jetonu veya IBuffer
nesnesini kullanarak arabelleği referans alabilir ya da arabellekle etkileşim kurabilir.
IDevice::allocate
kaynağından alınan jeton, arabelleğe bir yürütmenin Request
yapısındaki MemoryPool
nesnelerinden biri olarak referans verildiğinde sağlanır. Bir işlemin başka bir işlemde ayrılan arabelleğe erişmeye çalışmasını önlemek için sürücünün, arabelleğin her kullanımında uygun doğrulamayı uygulaması gerekir. Sürücü, arabellek kullanımının, tahsis sırasında sağlanan BufferRole
rollerinden biri olduğunu doğrulamalı ve kullanım yasa dışıysa yürütmeyi hemen iptal etmelidir.
IBuffer
nesnesi, açık bellek kopyalama için kullanılır. Belirli durumlarda, sürücünün istemcisi, sürücü tarafından yönetilen arabelleği paylaşılan bir bellek havuzundan başlatmalı veya arabelleği paylaşılan bir bellek havuzuna kopyalamalıdır. Örnek kullanım alanları:
- Durum tensörünün başlatılması
- Ara sonuçları önbelleğe alma
- CPU'da yedek yürütme
Bu kullanım alanlarını desteklemek için sürücünün, bellek alanı tahsisini destekliyorsa ashmem
, mmap_fd
ve hardware_buffer_blob
ile IBuffer::copyTo
ve IBuffer::copyFrom
özelliklerini uygulaması gerekir. Sürücünün BLOB olmayan modu desteklemesi isteğe bağlıdırhardware_buffer
.
Arabellek ayırma sırasında, arabelleğin boyutları BufferRole
tarafından belirtilen tüm rollerin karşılık gelen model operatörlerinden ve BufferDesc
içinde sağlanan boyutlardan çıkarılabilir. Tüm boyut bilgilerinin birleştirilmesiyle arabellek, bilinmeyen boyutlara veya sıralamaya sahip olabilir. Bu durumda, arabellek, model girişi olarak kullanıldığında boyutların sabit olduğu esnek bir durumda, model çıkışı olarak kullanıldığında ise dinamik bir durumdadır. Aynı arabellek, farklı yürütmelerde farklı çıkış şekilleriyle kullanılabilir ve sürücü, arabelleğin yeniden boyutlandırılmasını düzgün şekilde yapmalıdır.
Bellek alanı isteğe bağlı bir özelliktir. Sürücü, belirli bir tahsis isteğini çeşitli nedenlerle destekleyemeyeceğini belirleyebilir. Örnek:
- İstenen arabellek dinamik boyuta sahip.
- Sürücü, büyük arabellekleri işlemesini engelleyen bellek kısıtlamalarına sahiptir.
Sürücü tarafından yönetilen arabellekten birkaç farklı iş parçacığının aynı anda okuma yapması mümkündür. Yazma veya okuma/yazma için arabelleğe aynı anda erişmek tanımlanmamıştır ancak sürücü hizmetini kilitlememeli veya arayanı süresiz olarak engellememelidir. Sürücü bir hata döndürebilir veya arabelleğin içeriğini belirsiz durumda bırakabilir.