18b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet/* 28b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * Copyright (C) 2017 The Android Open Source Project 38b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * 48b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * Licensed under the Apache License, Version 2.0 (the "License"); 58b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * you may not use this file except in compliance with the License. 68b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * You may obtain a copy of the License at 78b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * 88b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * http://www.apache.org/licenses/LICENSE-2.0 98b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * 108b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * Unless required by applicable law or agreed to in writing, software 118b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * distributed under the License is distributed on an "AS IS" BASIS, 128b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * See the License for the specific language governing permissions and 148b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet * limitations under the License. 158b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet */ 168b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 178b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet#ifndef ANDROID_ML_NN_RUNTIME_MEMORY_H 188b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet#define ANDROID_ML_NN_RUNTIME_MEMORY_H 198b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 208b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet#include "NeuralNetworks.h" 218b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet#include "Utils.h" 228b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 23105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang#include <cutils/native_handle.h> 24105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang#include <sys/mman.h> 258b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet#include <unordered_map> 268b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 278b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouilletnamespace android { 288b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouilletnamespace nn { 298b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 308b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouilletclass ModelBuilder; 318b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 322150f1d186b2854fb5aa609594be12a667f845f0Jean-Luc Brouillet// Represents a memory region. 338b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouilletclass Memory { 348b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouilletpublic: 35105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang Memory() {} 36105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang virtual ~Memory() {} 37105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang 38105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang // Disallow copy semantics to ensure the runtime object can only be freed 39105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang // once. Copy semantics could be enabled if some sort of reference counting 40105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang // or deep-copy system for runtime objects is added later. 41105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang Memory(const Memory&) = delete; 42105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang Memory& operator=(const Memory&) = delete; 43105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang 448b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // Creates a shared memory object of the size specified in bytes. 458b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet int create(uint32_t size); 468b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 478b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet hardware::hidl_memory getHidlMemory() const { return mHidlMemory; } 488b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 492150f1d186b2854fb5aa609594be12a667f845f0Jean-Luc Brouillet // Returns a pointer to the underlying memory of this memory object. 50105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang virtual int getPointer(uint8_t** buffer) const { 512150f1d186b2854fb5aa609594be12a667f845f0Jean-Luc Brouillet *buffer = static_cast<uint8_t*>(static_cast<void*>(mMemory->getPointer())); 522150f1d186b2854fb5aa609594be12a667f845f0Jean-Luc Brouillet return ANEURALNETWORKS_NO_ERROR; 538b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet } 548b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 55e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet virtual bool validateSize(uint32_t offset, uint32_t length) const; 56105807d963d969197fe78185ed588bfad3dc0ea5Miao Wangprotected: 578b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // The hidl_memory handle for this shared memory. We will pass this value when 588b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // communicating with the drivers. 598b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet hardware::hidl_memory mHidlMemory; 608b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet sp<IMemory> mMemory; 618b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet}; 628b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 63105807d963d969197fe78185ed588bfad3dc0ea5Miao Wangclass MemoryFd : public Memory { 64105807d963d969197fe78185ed588bfad3dc0ea5Miao Wangpublic: 65105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang MemoryFd() {} 66e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet ~MemoryFd(); 67105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang 68105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang // Disallow copy semantics to ensure the runtime object can only be freed 69105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang // once. Copy semantics could be enabled if some sort of reference counting 70105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang // or deep-copy system for runtime objects is added later. 71105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang MemoryFd(const MemoryFd&) = delete; 72105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang MemoryFd& operator=(const MemoryFd&) = delete; 73105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang 74105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang // Create the native_handle based on input size, prot, and fd. 75105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang // Existing native_handle will be deleted, and mHidlMemory will wrap 76105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang // the newly created native_handle. 77e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet int set(size_t size, int prot, int fd, size_t offset); 78105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang 79e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet int getPointer(uint8_t** buffer) const override; 80105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang 81105807d963d969197fe78185ed588bfad3dc0ea5Miao Wangprivate: 82105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang native_handle_t* mHandle = nullptr; 83fc43986520df188b3d099f3582c65c1f55c5f35eDavid Gross mutable uint8_t* mMapping = nullptr; 84105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang}; 85105807d963d969197fe78185ed588bfad3dc0ea5Miao Wang 868b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet// A utility class to accumulate mulitple Memory objects and assign each 878b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet// a distinct index number, starting with 0. 882150f1d186b2854fb5aa609594be12a667f845f0Jean-Luc Brouillet// 892150f1d186b2854fb5aa609594be12a667f845f0Jean-Luc Brouillet// The user of this class is responsible for avoiding concurrent calls 902150f1d186b2854fb5aa609594be12a667f845f0Jean-Luc Brouillet// to this class from multiple threads. 918b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouilletclass MemoryTracker { 924cb4fa2fe863a8f404c0448da160dd5bb4187db4David Grossprivate: 934cb4fa2fe863a8f404c0448da160dd5bb4187db4David Gross // The vector of Memory pointers we are building. 944cb4fa2fe863a8f404c0448da160dd5bb4187db4David Gross std::vector<const Memory*> mMemories; 954cb4fa2fe863a8f404c0448da160dd5bb4187db4David Gross // A faster way to see if we already have a memory than doing find(). 964cb4fa2fe863a8f404c0448da160dd5bb4187db4David Gross std::unordered_map<const Memory*, uint32_t> mKnown; 974cb4fa2fe863a8f404c0448da160dd5bb4187db4David Gross 988b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouilletpublic: 998b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // Adds the memory, if it does not already exists. Returns its index. 1008b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // The memories should survive the tracker. 1018b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet uint32_t add(const Memory* memory); 1028b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // Returns the number of memories contained. 1038b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet uint32_t size() const { return static_cast<uint32_t>(mKnown.size()); } 1048b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // Returns the ith memory. 1058b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet const Memory* operator[](size_t i) const { return mMemories[i]; } 1064cb4fa2fe863a8f404c0448da160dd5bb4187db4David Gross // Iteration 1074cb4fa2fe863a8f404c0448da160dd5bb4187db4David Gross decltype(mMemories.begin()) begin() { return mMemories.begin(); } 1084cb4fa2fe863a8f404c0448da160dd5bb4187db4David Gross decltype(mMemories.end()) end() { return mMemories.end(); } 1098b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet}; 1108b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 1112150f1d186b2854fb5aa609594be12a667f845f0Jean-Luc Brouillet} // namespace nn 1122150f1d186b2854fb5aa609594be12a667f845f0Jean-Luc Brouillet} // namespace android 1138b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 1142150f1d186b2854fb5aa609594be12a667f845f0Jean-Luc Brouillet#endif // ANDROID_ML_NN_RUNTIME_MEMORY_H 115