মেমরি পুল

এই পৃষ্ঠাটি ড্রাইভার এবং ফ্রেমওয়ার্কের মধ্যে অপারেন্ড বাফারগুলিকে দক্ষতার সাথে যোগাযোগ করতে ব্যবহৃত ডেটা কাঠামো এবং পদ্ধতিগুলি বর্ণনা করে।

মডেল কম্পাইলেশনের সময়, ফ্রেমওয়ার্ক ড্রাইভারকে ধ্রুবক অপারেন্ডের মান প্রদান করে। ধ্রুবক অপারেন্ডের জীবনকালের উপর নির্ভর করে, এর মানগুলি একটি HIDL ভেক্টর বা একটি ভাগ করা মেমরি পুলে অবস্থিত।

  • জীবনকাল CONSTANT_COPY হলে, মানগুলি মডেল কাঠামোর operandValues ক্ষেত্রে অবস্থিত। যেহেতু এইচআইডিএল ভেক্টরের মানগুলি ইন্টারপ্রসেস কমিউনিকেশনের (আইপিসি) সময় অনুলিপি করা হয়, এটি সাধারণত শুধুমাত্র অল্প পরিমাণ ডেটা যেমন স্কেলার অপারেন্ড (উদাহরণস্বরূপ, ADD এ অ্যাক্টিভেশন স্কেলার) এবং ছোট টেনসর প্যারামিটার (উদাহরণস্বরূপ, RESHAPE এ আকৃতির টেনসর)।
  • যদি জীবনকাল CONSTANT_REFERENCE হয়, মানগুলি মডেল কাঠামোর pools ক্ষেত্রে অবস্থিত। শুধুমাত্র শেয়ার্ড মেমরি পুলের হ্যান্ডেলগুলি আইপিসি চলাকালীন কাঁচা মান অনুলিপি করার পরিবর্তে নকল করা হয়। অতএব, HIDL ভেক্টরের তুলনায় শেয়ার্ড মেমরি পুল ব্যবহার করে প্রচুর পরিমাণে ডেটা (উদাহরণস্বরূপ, কনভল্যুশনে ওজনের প্যারামিটার) রাখা আরও দক্ষ।

মডেল এক্সিকিউশনের সময়, ফ্রেমওয়ার্ক ড্রাইভারকে ইনপুট এবং আউটপুট অপারেন্ডের বাফার প্রদান করে। HIDL ভেক্টরে পাঠানো কম্পাইল-টাইম কনস্ট্যান্টের বিপরীতে, একটি এক্সিকিউশনের ইনপুট এবং আউটপুট ডেটা সবসময় মেমরি পুলের সংগ্রহের মাধ্যমে যোগাযোগ করা হয়।

HIDL ডেটা টাইপ hidl_memory একটি আনম্যাপ করা শেয়ার্ড মেমরি পুল উপস্থাপন করতে সংকলন এবং সম্পাদন উভয় ক্ষেত্রেই ব্যবহৃত হয়। hidl_memory ডেটা টাইপের নামের উপর ভিত্তি করে এটিকে ব্যবহারযোগ্য করার জন্য ড্রাইভারকে সেই অনুযায়ী মেমরি ম্যাপ করা উচিত। সমর্থিত মেমরির নামগুলি হল:

  • ashmem : অ্যান্ড্রয়েড শেয়ার করা মেমরি। আরও বিস্তারিত জানার জন্য, মেমরি দেখুন।
  • mmap_fd : mmap এর মাধ্যমে একটি ফাইল বর্ণনাকারী দ্বারা সমর্থিত শেয়ার করা মেমরি।
  • hardware_buffer_blob : শেয়ার করা মেমরি AHARDWARE_BUFFER_FORMAT_BLOB ফরম্যাট সহ একটি AHardwareBuffer দ্বারা সমর্থিত। নিউরাল নেটওয়ার্ক (NN) HAL 1.2 থেকে উপলব্ধ। আরো বিস্তারিত জানার জন্য, AHardwareBuffer দেখুন।
  • hardware_buffer : একটি সাধারণ AHardwareBuffer দ্বারা সমর্থিত শেয়ার করা মেমরি যা AHARDWARE_BUFFER_FORMAT_BLOB বিন্যাস ব্যবহার করে না। নন-ব্লব মোড হার্ডওয়্যার বাফার শুধুমাত্র মডেল এক্সিকিউশনে সমর্থিত। NN HAL 1.2 থেকে উপলব্ধ। আরো বিস্তারিত জানার জন্য, AHardwareBuffer দেখুন।

NN HAL 1.3 থেকে, NNAPI মেমরি ডোমেন সমর্থন করে যা ড্রাইভার-পরিচালিত বাফারগুলির জন্য বরাদ্দকারী ইন্টারফেস প্রদান করে। ড্রাইভার-পরিচালিত বাফারগুলি এক্সিকিউশন ইনপুট বা আউটপুট হিসাবেও ব্যবহার করা যেতে পারে। আরো বিস্তারিত জানার জন্য, মেমরি ডোমেন দেখুন।

NNAPI ড্রাইভারদের অবশ্যই ashmem এবং mmap_fd মেমরি নামের ম্যাপিং সমর্থন করতে হবে। NN HAL 1.3 থেকে, ড্রাইভারদের অবশ্যই hardware_buffer_blob এর ম্যাপিং সমর্থন করতে হবে। সাধারণ নন-ব্লব মোড hardware_buffer এবং মেমরি ডোমেনগুলির জন্য সমর্থন ঐচ্ছিক।

AHardwareBuffer

AHardwareBuffer হল এক ধরনের শেয়ার করা মেমরি যা একটি Gralloc বাফারকে মোড়ানো হয়। অ্যান্ড্রয়েড 10-এ, নিউরাল নেটওয়ার্ক এপিআই (এনএনএপিআই) AHardwareBuffer ব্যবহার করে সমর্থন করে, যা ড্রাইভারকে ডেটা অনুলিপি না করে মৃত্যুদন্ড সম্পাদন করতে দেয়, যা অ্যাপগুলির কর্মক্ষমতা এবং পাওয়ার খরচ উন্নত করে। উদাহরণস্বরূপ, ক্যামেরা এনডিকে এবং মিডিয়া এনডিকে এপিআই দ্বারা উত্পন্ন AHardwareBuffer হ্যান্ডেলগুলি ব্যবহার করে একটি ক্যামেরা HAL স্ট্যাক মেশিন লার্নিং ওয়ার্কলোডের জন্য NNAPI-তে AHardwareBuffer অবজেক্টগুলি প্রেরণ করতে পারে। আরও তথ্যের জন্য, ANeuralNetworksMemory_createFromAHardwareBuffer দেখুন।

NNAPI তে ব্যবহৃত AHardwareBuffer অবজেক্টগুলিকে hardware_buffer বা hardware_buffer_blob নামে একটি hidl_memory struct এর মাধ্যমে ড্রাইভারের কাছে পাঠানো হয়। hidl_memory struct hardware_buffer_blob শুধুমাত্র AHARDWAREBUFFER_FORMAT_BLOB ফর্ম্যাট সহ AHardwareBuffer অবজেক্টগুলিকে উপস্থাপন করে।

ফ্রেমওয়ার্কের জন্য প্রয়োজনীয় তথ্য hidl_memory struct-এর hidl_handle ক্ষেত্রে এনকোড করা হয়। hidl_handle ক্ষেত্রটি native_handle র্যাপ করে, যা AHardwareBuffer বা Gralloc বাফার সম্পর্কে প্রয়োজনীয় সমস্ত মেটাডেটা এনকোড করে।

ড্রাইভারকে অবশ্যই প্রদত্ত hidl_handle ক্ষেত্রটি সঠিকভাবে ডিকোড করতে হবে এবং hidl_handle দ্বারা বর্ণিত মেমরি অ্যাক্সেস করতে হবে। যখন getSupportedOperations_1_2 , getSupportedOperations_1_1 , বা getSupportedOperations পদ্ধতি বলা হয়, তখন ড্রাইভারকে সনাক্ত করা উচিত যে এটি প্রদত্ত hidl_handle ডিকোড করতে পারে এবং hidl_handle দ্বারা বর্ণিত মেমরি অ্যাক্সেস করতে পারে কিনা। একটি ধ্রুবক অপারেন্ডের জন্য ব্যবহৃত hidl_handle ক্ষেত্রটি সমর্থিত না হলে মডেল প্রস্তুতি অবশ্যই ব্যর্থ হবে। এক্সিকিউশনের ইনপুট বা আউটপুট অপারেন্ডের জন্য ব্যবহৃত hidl_handle ফিল্ডটি সমর্থিত না হলে এক্সিকিউশন অবশ্যই ব্যর্থ হবে। মডেল প্রস্তুতি বা সম্পাদন ব্যর্থ হলে ড্রাইভারকে একটি GENERAL_FAILURE ত্রুটি কোড ফেরত দেওয়ার পরামর্শ দেওয়া হয়।

মেমরি ডোমেইন

Android 11 বা উচ্চতর সংস্করণে চলমান ডিভাইসগুলির জন্য, NNAPI মেমরি ডোমেন সমর্থন করে যা ড্রাইভার-পরিচালিত বাফারগুলির জন্য বরাদ্দকারী ইন্টারফেস প্রদান করে। এটি মৃত্যুদন্ড জুড়ে ডিভাইসের নেটিভ স্মৃতিগুলি পাস করার অনুমতি দেয়, অপ্রয়োজনীয় ডেটা অনুলিপি দমন করে এবং একই ড্রাইভারে ক্রমাগত মৃত্যুদন্ডের মধ্যে রূপান্তর করে। এই প্রবাহটি চিত্র 1 এ চিত্রিত করা হয়েছে।

মেমরি ডোমেন সহ এবং ছাড়া বাফার ডেটা প্রবাহ

চিত্র 1. মেমরি ডোমেন ব্যবহার করে বাফার ডেটা প্রবাহ

মেমরি ডোমেন বৈশিষ্ট্যটি টেনসরগুলির জন্য উদ্দিষ্ট যেগুলি বেশিরভাগ ড্রাইভারের অভ্যন্তরীণ এবং ক্লায়েন্টের দিকে ঘন ঘন অ্যাক্সেসের প্রয়োজন হয় না। এই ধরনের টেনসরের উদাহরণগুলির মধ্যে রয়েছে সিকোয়েন্স মডেলের স্টেট টেনসর। ক্লায়েন্ট সাইডে ঘন ঘন CPU অ্যাক্সেসের প্রয়োজন হয় এমন টেনসরগুলির জন্য, শেয়ার্ড মেমরি পুল ব্যবহার করা বাঞ্ছনীয়।

মেমরি ডোমেন বৈশিষ্ট্য সমর্থন করতে, ড্রাইভার-পরিচালিত বাফার বরাদ্দের জন্য ফ্রেমওয়ার্ককে অনুরোধ করার অনুমতি দেওয়ার জন্য IDevice::allocate প্রয়োগ করুন। বরাদ্দের সময়, ফ্রেমওয়ার্ক বাফারের জন্য নিম্নলিখিত বৈশিষ্ট্য এবং ব্যবহারের নিদর্শন প্রদান করে:

  • BufferDesc বাফারের প্রয়োজনীয় বৈশিষ্ট্য বর্ণনা করে।
  • BufferRole একটি প্রস্তুত মডেলের ইনপুট বা আউটপুট হিসাবে বাফারের সম্ভাব্য ব্যবহার প্যাটার্ন বর্ণনা করে। বাফার বরাদ্দের সময় একাধিক ভূমিকা নির্দিষ্ট করা যেতে পারে, এবং বরাদ্দ করা বাফার শুধুমাত্র সেই নির্দিষ্ট ভূমিকা হিসাবে ব্যবহার করা যেতে পারে।

বরাদ্দকৃত বাফারটি ড্রাইভারের অভ্যন্তরীণ। একজন ড্রাইভার যেকোনো বাফার অবস্থান বা ডেটা লেআউট বেছে নিতে পারে। যখন বাফারটি সফলভাবে বরাদ্দ করা হয়, তখন ড্রাইভারের ক্লায়েন্ট রিটার্ন করা টোকেন বা IBuffer অবজেক্ট ব্যবহার করে বাফারের সাথে রেফারেন্স বা ইন্টারঅ্যাক্ট করতে পারে।

একটি এক্সিকিউশনের Request স্ট্রাকচারে MemoryPool অবজেক্টের একটি হিসাবে বাফারকে উল্লেখ করার সময় IDevice::allocate থেকে টোকেন প্রদান করা হয়। একটি প্রক্রিয়াকে অন্য প্রক্রিয়ায় বরাদ্দকৃত বাফার অ্যাক্সেস করার চেষ্টা থেকে প্রতিরোধ করতে, ড্রাইভারকে অবশ্যই বাফারের প্রতিটি ব্যবহারে যথাযথ বৈধতা প্রয়োগ করতে হবে। ড্রাইভারকে অবশ্যই যাচাই করতে হবে যে বাফার ব্যবহারটি বরাদ্দের সময় প্রদত্ত BufferRole ভূমিকাগুলির মধ্যে একটি এবং ব্যবহারটি অবৈধ হলে অবিলম্বে কার্যকর করতে ব্যর্থ হবে৷

IBuffer অবজেক্টটি সুস্পষ্ট মেমরি কপি করার জন্য ব্যবহৃত হয়। নির্দিষ্ট পরিস্থিতিতে, ড্রাইভারের ক্লায়েন্টকে অবশ্যই একটি শেয়ার্ড মেমরি পুল থেকে ড্রাইভার-পরিচালিত বাফার শুরু করতে হবে বা বাফারটিকে একটি শেয়ার্ড মেমরি পুলে কপি করতে হবে। উদাহরণ ব্যবহারের ক্ষেত্রে অন্তর্ভুক্ত:

  • রাষ্ট্রীয় টেনসরের সূচনা
  • ক্যাশিং মধ্যবর্তী ফলাফল
  • CPU-তে ফলব্যাক এক্সিকিউশন

এই ব্যবহারের ক্ষেত্রে সমর্থন করার জন্য, ড্রাইভারকে অবশ্যই IBuffer::copyTo এবং IBuffer::copyFrom এর সাথে ashmem , mmap_fd , এবং hardware_buffer_blob প্রয়োগ করতে হবে যদি এটি মেমরি ডোমেন বরাদ্দ সমর্থন করে। ড্রাইভারের পক্ষে নন-ব্লব মোড hardware_buffer সমর্থন করা ঐচ্ছিক।

বাফার বরাদ্দের সময়, বাফারের মাত্রাগুলি BufferRole দ্বারা নির্দিষ্ট করা সমস্ত ভূমিকার সংশ্লিষ্ট মডেল অপারেন্ড এবং BufferDesc এ প্রদত্ত মাত্রাগুলি থেকে অনুমান করা যেতে পারে। সমস্ত মাত্রিক তথ্য একত্রিত করে, বাফারের অজানা মাত্রা বা র‍্যাঙ্ক থাকতে পারে। এই ধরনের ক্ষেত্রে, বাফারটি একটি নমনীয় অবস্থায় থাকে যেখানে একটি মডেল ইনপুট হিসাবে ব্যবহার করার সময় মাত্রাগুলি স্থির করা হয় এবং একটি মডেল আউটপুট হিসাবে ব্যবহার করার সময় একটি গতিশীল অবস্থায়। একই বাফার বিভিন্ন এক্সিকিউশনে বিভিন্ন আকারের আউটপুটের সাথে ব্যবহার করা যেতে পারে এবং ড্রাইভারকে অবশ্যই বাফারের আকার পরিবর্তন সঠিকভাবে পরিচালনা করতে হবে।

মেমরি ডোমেন একটি ঐচ্ছিক বৈশিষ্ট্য। একজন ড্রাইভার নির্ধারণ করতে পারে যে এটি বিভিন্ন কারণে একটি প্রদত্ত বরাদ্দের অনুরোধ সমর্থন করতে পারে না। যেমন:

  • অনুরোধ করা বাফার একটি গতিশীল আকার আছে.
  • ড্রাইভারের মেমরির সীমাবদ্ধতা রয়েছে যা এটিকে বড় বাফারগুলি পরিচালনা করতে বাধা দেয়।

ড্রাইভার-পরিচালিত বাফার থেকে একসাথে বিভিন্ন থ্রেড পড়া সম্ভব। লিখতে বা পড়া/লেখার জন্য একই সাথে বাফার অ্যাক্সেস করা অনির্ধারিত, তবে এটি অবশ্যই ড্রাইভার পরিষেবাকে ক্র্যাশ করবে না বা কলকারীকে অনির্দিষ্টকালের জন্য ব্লক করবে না। ড্রাইভার একটি ত্রুটি ফেরত দিতে পারে বা বাফারের বিষয়বস্তু একটি অনির্দিষ্ট অবস্থায় রেখে যেতে পারে।