196775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet/* 296775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet * Copyright (C) 2017 The Android Open Source Project 396775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet * 496775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet * Licensed under the Apache License, Version 2.0 (the "License"); 596775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet * you may not use this file except in compliance with the License. 696775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet * You may obtain a copy of the License at 796775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet * 896775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet * http://www.apache.org/licenses/LICENSE-2.0 996775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet * 1096775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet * Unless required by applicable law or agreed to in writing, software 1196775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet * distributed under the License is distributed on an "AS IS" BASIS, 1296775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1396775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet * See the License for the specific language governing permissions and 1496775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet * limitations under the License. 1596775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet */ 1696775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet 173ced3cfd5b8f22b632c35f24e585c4847383b195David Gross#ifndef ANDROID_ML_NN_RUNTIME_EXECUTION_BUILDER_H 183ced3cfd5b8f22b632c35f24e585c4847383b195David Gross#define ANDROID_ML_NN_RUNTIME_EXECUTION_BUILDER_H 1996775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet 20033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler#include "Callbacks.h" 21707dbd2d55f5dacf78ffb3ad7c8b3f37c2e9d758Jean-Luc Brouillet#include "HalInterfaces.h" 228b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet#include "Memory.h" 2396811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross#include "ModelBuilder.h" 2496775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet#include "NeuralNetworks.h" 2596775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet 268b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet#include <unordered_map> 27707dbd2d55f5dacf78ffb3ad7c8b3f37c2e9d758Jean-Luc Brouillet#include <vector> 28707dbd2d55f5dacf78ffb3ad7c8b3f37c2e9d758Jean-Luc Brouillet 29033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlerusing ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback; 30033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlerusing ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback; 31689d892203c06c66c7bb2e374462a8434e40b75fMichael Butler 3296775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouilletnamespace android { 3396775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouilletnamespace nn { 3496775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet 3583e24dc4706a5b7089881a55daf05b3924fab3b7David Grossclass CompilationBuilder; 361f4381539b7e89c42336ee7cd1addb9a4c317b34David Grossclass ExecutionPlan; 378b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouilletclass Memory; 38707dbd2d55f5dacf78ffb3ad7c8b3f37c2e9d758Jean-Luc Brouilletclass ModelBuilder; 39b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Grossclass StepExecutor; 40aba8381570d7cc4b5431d741132d6f80519201ebMichael Butlerclass VersionedIDevice; 41707dbd2d55f5dacf78ffb3ad7c8b3f37c2e9d758Jean-Luc Brouillet 428b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet// TODO move length out of DataLocation 438b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouilletstruct ModelArgumentInfo { 4462cc2758c1c2d303861e209f26bddcf4d7564b73Jean-Luc Brouillet // Whether the argument was specified as being in a Memory, as a pointer, 4562cc2758c1c2d303861e209f26bddcf4d7564b73Jean-Luc Brouillet // has no value, or has not been specified. 468b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // If POINTER then: 4762cc2758c1c2d303861e209f26bddcf4d7564b73Jean-Luc Brouillet // locationAndLength.length is valid. 4862cc2758c1c2d303861e209f26bddcf4d7564b73Jean-Luc Brouillet // dimensions is valid. 498b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // buffer is valid 508b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // If MEMORY then: 51c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // locationAndLength.{poolIndex, offset, length} is valid. 5262cc2758c1c2d303861e209f26bddcf4d7564b73Jean-Luc Brouillet // dimensions is valid. 5362cc2758c1c2d303861e209f26bddcf4d7564b73Jean-Luc Brouillet enum { POINTER, MEMORY, HAS_NO_VALUE, UNSPECIFIED } state = UNSPECIFIED; 5462cc2758c1c2d303861e209f26bddcf4d7564b73Jean-Luc Brouillet DataLocation locationAndLength; 5562cc2758c1c2d303861e209f26bddcf4d7564b73Jean-Luc Brouillet std::vector<uint32_t> dimensions; 568b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet void* buffer; 57389f26c7c442c37994db9f43d013fe3953c9353cJean-Luc Brouillet 58389f26c7c442c37994db9f43d013fe3953c9353cJean-Luc Brouillet int setFromPointer(const Operand& operand, const ANeuralNetworksOperandType* type, void* buffer, 59389f26c7c442c37994db9f43d013fe3953c9353cJean-Luc Brouillet uint32_t length); 60389f26c7c442c37994db9f43d013fe3953c9353cJean-Luc Brouillet int setFromMemory(const Operand& operand, const ANeuralNetworksOperandType* type, 61389f26c7c442c37994db9f43d013fe3953c9353cJean-Luc Brouillet uint32_t poolIndex, uint32_t offset, uint32_t length); 628fb14e90ceb360adfbac0f708d27161b7c5b7fc5David Gross int setFromTemporaryMemory(const Operand& operand, uint32_t poolIndex, uint32_t offset); 63389f26c7c442c37994db9f43d013fe3953c9353cJean-Luc Brouillet int updateDimensionInfo(const Operand& operand, const ANeuralNetworksOperandType* newType); 648b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet}; 658b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 663ced3cfd5b8f22b632c35f24e585c4847383b195David Grossclass ExecutionBuilder { 67b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross friend class StepExecutor; 6896775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouilletpublic: 693ced3cfd5b8f22b632c35f24e585c4847383b195David Gross ExecutionBuilder(const CompilationBuilder* compilation); 7096775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet 7196775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet int setInput(uint32_t index, const ANeuralNetworksOperandType* type, const void* buffer, 72e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet size_t length); 738b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet int setInputFromMemory(uint32_t index, const ANeuralNetworksOperandType* type, 74e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet const Memory* memory, size_t offset, size_t length); 7596775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet int setOutput(uint32_t index, const ANeuralNetworksOperandType* type, void* buffer, 76e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet size_t length); 778b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet int setOutputFromMemory(uint32_t index, const ANeuralNetworksOperandType* type, 78e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet const Memory* memory, size_t offset, size_t length); 79033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler int startCompute(sp<ExecutionCallback>* synchronizationCallback); 8096775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet 8196811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross const ModelBuilder* getModel() const { return mModel; } 8296811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross 8396775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouilletprivate: 84b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross const ModelBuilder* mModel; 85e3178825b8686f3300a895572691a2e8c1f0676bDavid Gross const ExecutionPlan* mPlan; 86b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross 87c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross // This is a DeviceManager::kPartitioning* value captured from 88c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross // CompilationBuilder when the ExecutionBuilder is constructed. 89c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross uint32_t mPartitioning; 90c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross 91b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // The information we'll send to the driver about the inputs and outputs. 92b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // Note that we build this in two steps: 93b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // 1. As the arguments are specified, set the corresponding mInputs or mOutputs element. 94b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // If set from a pointer, don't set the location in the RequestArgument but store it 95b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // instead in mInputBuffers or mOutputBuffers. 96b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // 2. Once we have all the inputs and outputs, if needed, allocate shared memory for 97b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // the m*Buffers entries. Copy the input values into the shared memory. 98b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // We do this to avoid creating a lot of shared memory objects if we have a lot of 99b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // parameters specified via pointers. We also avoid copying in the case where 100b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // some of the nodes will interpreted on the CPU anyway. 101b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross std::vector<ModelArgumentInfo> mInputs; 102b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross std::vector<ModelArgumentInfo> mOutputs; 103b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross MemoryTracker mMemories; 104b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross}; 105b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross 106b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross// class StepExecutor is used to execute a single "step" in a 107b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross// potentially multiple step execution process. The graph associated 108b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross// with that step is executed in its entirety on a single device (or 109b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross// on the CPU). 110b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Grossclass StepExecutor { 111b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Grosspublic: 112b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // executionBuilder 113b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // Describes the full (possibly multiple-"step") execution. 114b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // model 115b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // The model to be executed by the executor. Possibly a 116b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // submodel of the model from executionBuilder. 117b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // driver, preparedModel 118b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // The device on which to execute the "step", and the prepared 119b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // model to execute on that device. (Both are nullptr in the 120b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // case of CPU.) 121b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross StepExecutor(const ExecutionBuilder* executionBuilder, 122b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross const ModelBuilder* model, 12375886e77f9ca074173a49283b5c0a8c182d98977Michael Butler VersionedIDevice* driver, sp<IPreparedModel> preparedModel); 124b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross 125b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // Map inputs and outputs from ExecutionBuilder to StepExecutor, 126b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // in the case where we have a single-"step" execution (i.e., the executor 127b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // is executing the entire model from the ExecutionBuilder). 128b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross void mapInputsAndOutputsTrivially(); 129b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross 130891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross // Map inputs and outputs from ExecutionBuilder to StepExecutor, 131891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross // one at a time. Note that these are input/output indexes, not 132891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross // operand indexes. 133891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross void mapInput(uint32_t builderIndex, uint32_t executorIndex) { 134891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross mapInputOrOutput(mExecutionBuilder->mInputs[builderIndex], 135891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross &mInputs[executorIndex]); 136891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross } 137891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross void mapOutput(uint32_t builderIndex, uint32_t executorIndex) { 138891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross mapInputOrOutput(mExecutionBuilder->mOutputs[builderIndex], 139891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross &mOutputs[executorIndex]); 140891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross } 141c4c264098a728268ad28084ea6e0263d9c1d7868David Gross void mapOutputToInput(uint32_t builderIndex, uint32_t executorIndex) { 142c4c264098a728268ad28084ea6e0263d9c1d7868David Gross mapInputOrOutput(mExecutionBuilder->mOutputs[builderIndex], 143c4c264098a728268ad28084ea6e0263d9c1d7868David Gross &mInputs[executorIndex]); 144c4c264098a728268ad28084ea6e0263d9c1d7868David Gross } 145b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross 1468fb14e90ceb360adfbac0f708d27161b7c5b7fc5David Gross // The input or output is assumed to have the size of the 1478fb14e90ceb360adfbac0f708d27161b7c5b7fc5David Gross // corresponding operand. 1488fb14e90ceb360adfbac0f708d27161b7c5b7fc5David Gross int setInputFromTemporaryMemory(uint32_t inputIndex, const Memory* memory, uint32_t offset) { 14996811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross return setInputOrOutputFromTemporaryMemory(mModel->getInputOperand(inputIndex), 1508fb14e90ceb360adfbac0f708d27161b7c5b7fc5David Gross memory, offset, 15196811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross &mInputs.at(inputIndex)); 15296811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross } 1538fb14e90ceb360adfbac0f708d27161b7c5b7fc5David Gross int setOutputFromTemporaryMemory(uint32_t outputIndex, const Memory* memory, uint32_t offset) { 15496811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross return setInputOrOutputFromTemporaryMemory(mModel->getOutputOperand(outputIndex), 1558fb14e90ceb360adfbac0f708d27161b7c5b7fc5David Gross memory, offset, 15696811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross &mOutputs.at(outputIndex)); 15796811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross } 158b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross 1595e8feed5e8a07bab1ec395e5a01bb8900db00cecDavid Gross // Executes using the (driver, preparedModel) specified at construction time. 160033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler int startCompute(sp<ExecutionCallback>* synchronizationCallback); 161b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross 1625e8feed5e8a07bab1ec395e5a01bb8900db00cecDavid Gross // Executes using the CPU, regardless of the (driver, 1635e8feed5e8a07bab1ec395e5a01bb8900db00cecDavid Gross // preparedModel) specified at construction time. 1645e8feed5e8a07bab1ec395e5a01bb8900db00cecDavid Gross int startComputeOnCpu(sp<ExecutionCallback>* synchronizationCallback); 1655e8feed5e8a07bab1ec395e5a01bb8900db00cecDavid Gross 1665e8feed5e8a07bab1ec395e5a01bb8900db00cecDavid Gross bool isCpu() const { return mDriver == nullptr; } 1675e8feed5e8a07bab1ec395e5a01bb8900db00cecDavid Gross 168b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Grossprivate: 1698b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet int allocatePointerArgumentsToPool(std::vector<ModelArgumentInfo>* args, Memory* memory); 170033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler int startComputeOnDevice(sp<ExecutionCallback>* synchronizationCallback); 17196775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet 172891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross void mapInputOrOutput(const ModelArgumentInfo& builderInputOrOutput, 173891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross ModelArgumentInfo* executorInputOrOutput); 174891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross 17596811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross int setInputOrOutputFromTemporaryMemory(const Operand& inputOrOutputOperand, 1768fb14e90ceb360adfbac0f708d27161b7c5b7fc5David Gross const Memory* memory, uint32_t offset, 17796811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross ModelArgumentInfo* inputOrOutputInfo); 17896811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross 179b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // describes the full (possibly multiple-"step") execution 180b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross const ExecutionBuilder* mExecutionBuilder; 181b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross 182b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // model to be executed on the executor, in both original and 183b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // compiled forms; and device on which to execute it 18496775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet const ModelBuilder* mModel; 18575886e77f9ca074173a49283b5c0a8c182d98977Michael Butler VersionedIDevice* mDriver; // nullptr if CPU execution 186b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross sp<IPreparedModel> mPreparedModel; // nullptr if CPU execution or if bypassing ExecutionPlan 1878b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet 188707dbd2d55f5dacf78ffb3ad7c8b3f37c2e9d758Jean-Luc Brouillet // The information we'll send to the driver about the inputs and outputs. 189707dbd2d55f5dacf78ffb3ad7c8b3f37c2e9d758Jean-Luc Brouillet // Note that we build this in two steps: 1908b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // 1. As the arguments are specified, set the corresponding mInputs or mOutputs element. 191a4e2ee81d015b5e26897d18b18dd50044faba62fJean-Luc Brouillet // If set from a pointer, don't set the location in the RequestArgument but store it 1928b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // instead in mInputBuffers or mOutputBuffers. 1938b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // 2. Once we have all the inputs and outputs, if needed, allocate shared memory for 1948b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // the m*Buffers entries. Copy the input values into the shared memory. 1958b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // We do this to avoid creating a lot of shared memory objects if we have a lot of 1968b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // parameters specified via pointers. We also avoid copying in the case where 1978b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet // some of the nodes will interpreted on the CPU anyway. 1988b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet std::vector<ModelArgumentInfo> mInputs; 1998b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet std::vector<ModelArgumentInfo> mOutputs; 2008b99bb1d98a42b67ba1c00e12c7abb3708cf7c05Jean-Luc Brouillet MemoryTracker mMemories; 20196775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet}; 20296775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet 20396775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet} // namespace nn 20496775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet} // namespace android 20596775128e3bcfdc5be51b62edc50309c83861fe8Jean-Luc Brouillet 2063ced3cfd5b8f22b632c35f24e585c4847383b195David Gross#endif // ANDROID_ML_NN_RUNTIME_EXECUTION_BUILDER_H 207