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