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