ExecutionPlan.h revision 57167f7ec8bfe682139a9a4d60cd8aa913899441
191e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet/* 291e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet * Copyright (C) 2017 The Android Open Source Project 391e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet * 491e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet * Licensed under the Apache License, Version 2.0 (the "License"); 591e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet * you may not use this file except in compliance with the License. 691e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet * You may obtain a copy of the License at 791e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet * 891e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet * http://www.apache.org/licenses/LICENSE-2.0 991e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet * 1091e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet * Unless required by applicable law or agreed to in writing, software 1191e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet * distributed under the License is distributed on an "AS IS" BASIS, 1291e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1391e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet * See the License for the specific language governing permissions and 1491e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet * limitations under the License. 1591e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet */ 1691e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet 1791e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet// Classes used to plan how to execute a model across multiple devices. 1891e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet 1991e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet#ifndef ANDROID_ML_NN_RUNTIME_EXECUTION_PLAN_H 2091e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet#define ANDROID_ML_NN_RUNTIME_EXECUTION_PLAN_H 2191e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet 2291e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet#include "HalInterfaces.h" 2391e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet#include "Memory.h" 2457167f7ec8bfe682139a9a4d60cd8aa913899441Michael Butler#include "ModelBuilder.h" 2591e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet#include "NeuralNetworks.h" 2691e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet#include "Utils.h" 2791e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet 288913ae3283de7752aed108c1b26aef1adacb049fDavid Gross#include <set> 298913ae3283de7752aed108c1b26aef1adacb049fDavid Gross 3091e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletnamespace android { 3191e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletnamespace nn { 3291e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet 3391e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletclass CompilationBuilder; 3491e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletclass Device; 35b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Grossclass ExecutionBuilder; 368913ae3283de7752aed108c1b26aef1adacb049fDavid Grossclass ExecutionPlan; 3791e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletclass Memory; 38b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Grossclass StepExecutor; 3991e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet 4091e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletclass ExecutionStep { 41c4c264098a728268ad28084ea6e0263d9c1d7868David Grosspublic: 428913ae3283de7752aed108c1b26aef1adacb049fDavid Gross typedef std::vector<std::pair<uint32_t, uint32_t>> RemapVectorType; 43b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross typedef std::set<std::pair<uint32_t, uint32_t>> SubModelOutputSetType; 448913ae3283de7752aed108c1b26aef1adacb049fDavid Gross 45f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross enum OperandKind { INPUT, OUTPUT }; 46f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross 478913ae3283de7752aed108c1b26aef1adacb049fDavid Gross ExecutionStep(ExecutionPlan* plan, 488913ae3283de7752aed108c1b26aef1adacb049fDavid Gross uint32_t stepIndex, 498913ae3283de7752aed108c1b26aef1adacb049fDavid Gross std::shared_ptr<Device> device); 5091e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet int addOperation(int operationIndex, const ModelBuilder& fromModel); 5191e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet int addOperand(uint32_t fromOperandIndex, uint32_t* toOperandIndex, 52f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross const ModelBuilder& fromModel, OperandKind kind); 5391e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet 5496811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross // Each container entry is of the form (fromModel index, subModel index) 5596811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross const RemapVectorType& getModelInputs() const { 5696811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross return mModelInputs; 5796811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross } 5896811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross const RemapVectorType& getModelOutputs() const { 5996811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross return mModelOutputs; 6096811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross } 61c4c264098a728268ad28084ea6e0263d9c1d7868David Gross const RemapVectorType& getTempsAsSubModelInputs() const { 62c4c264098a728268ad28084ea6e0263d9c1d7868David Gross return mTempsAsSubModelInputs; 638913ae3283de7752aed108c1b26aef1adacb049fDavid Gross } 64c4c264098a728268ad28084ea6e0263d9c1d7868David Gross const SubModelOutputSetType& getTempsAsSubModelOutputs() const { 65c4c264098a728268ad28084ea6e0263d9c1d7868David Gross return mTempsAsSubModelOutputs; 66c4c264098a728268ad28084ea6e0263d9c1d7868David Gross } 67c4c264098a728268ad28084ea6e0263d9c1d7868David Gross const RemapVectorType& getOutputsAsSubModelInputs() const { 68c4c264098a728268ad28084ea6e0263d9c1d7868David Gross return mOutputsAsSubModelInputs; 69c4c264098a728268ad28084ea6e0263d9c1d7868David Gross } 70c4c264098a728268ad28084ea6e0263d9c1d7868David Gross const std::vector<uint32_t>& getOutputsAsSubModelInputsIndexToFromModel() const { 71c4c264098a728268ad28084ea6e0263d9c1d7868David Gross return mOutputsAsSubModelInputsIndexToFromModel; 7296811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross } 73b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross 74c4c264098a728268ad28084ea6e0263d9c1d7868David Gross void recordTempAsSubModelOutput(uint32_t fromModelIndex) { 758913ae3283de7752aed108c1b26aef1adacb049fDavid Gross const auto it = mOperandMap.find(fromModelIndex); 768913ae3283de7752aed108c1b26aef1adacb049fDavid Gross nnAssert(it != mOperandMap.end()); 77c4c264098a728268ad28084ea6e0263d9c1d7868David Gross mTempsAsSubModelOutputs.insert(std::make_pair(fromModelIndex, it->second)); 788913ae3283de7752aed108c1b26aef1adacb049fDavid Gross } 798913ae3283de7752aed108c1b26aef1adacb049fDavid Gross 80b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // If this step has a submodel output of unknown size, sets 81b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // *hasOutputOfUnknownSize to true; otherwise, leaves it 82b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // unchanged. 83891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross int finishSubModel(const ModelBuilder* fromModel, bool* hasOutputOfUnknownSize); 84891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross 8557167f7ec8bfe682139a9a4d60cd8aa913899441Michael Butler const ModelBuilder* getSubModel() const { return &mSubModel; } 86891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross std::shared_ptr<Device> getDevice() const { return mDevice; } 87891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross 88891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross // only available after calling finishSubModel() 89891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross sp<IPreparedModel> getPreparedSubModel() const { return mPreparedSubModel; } 90891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross 91891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross // Map inputs and outputs from ExecutionBuilder to StepExecutor. 92891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross void mapInputsAndOutputs(std::shared_ptr<StepExecutor> stepExecutor) const; 938913ae3283de7752aed108c1b26aef1adacb049fDavid Gross 948913ae3283de7752aed108c1b26aef1adacb049fDavid Gross void dump() const; 95c4c264098a728268ad28084ea6e0263d9c1d7868David Gross 9691e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletprivate: 97c4c264098a728268ad28084ea6e0263d9c1d7868David Gross void logSubModel() const; 98c4c264098a728268ad28084ea6e0263d9c1d7868David Gross 99f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross // TODO: Some of the data is working state information that 100f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross // shouldn't be needed after we've constructed but not executed 101f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross // the step. 102f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross 1038913ae3283de7752aed108c1b26aef1adacb049fDavid Gross ExecutionPlan* mPlan; 1048913ae3283de7752aed108c1b26aef1adacb049fDavid Gross uint32_t mIndex; // index of step within plan 10557167f7ec8bfe682139a9a4d60cd8aa913899441Michael Butler ModelBuilder mSubModel; 1068913ae3283de7752aed108c1b26aef1adacb049fDavid Gross std::shared_ptr<Device> mDevice; // nullptr signifies CPU 1071f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross sp<IPreparedModel> mPreparedSubModel; // not used for CPU 108f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross 109f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross // Inputs of original model that are also inputs of this submodel: 110f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross // (fromModel index, subModel index) 1118913ae3283de7752aed108c1b26aef1adacb049fDavid Gross RemapVectorType mModelInputs; 112f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross // Outputs of original model that are also outputs of this submodel: 113f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross // (fromModel index, subModel index) 1148913ae3283de7752aed108c1b26aef1adacb049fDavid Gross RemapVectorType mModelOutputs; 115f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross // Temporaries of original model that are inputs of this submodel: 116f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross // (fromModel index, subModel index) 117c4c264098a728268ad28084ea6e0263d9c1d7868David Gross RemapVectorType mTempsAsSubModelInputs; 1188913ae3283de7752aed108c1b26aef1adacb049fDavid Gross // Temporaries of original model that are outputs of this submodel: 1198913ae3283de7752aed108c1b26aef1adacb049fDavid Gross // (fromModel index, subModel index) 120c4c264098a728268ad28084ea6e0263d9c1d7868David Gross SubModelOutputSetType mTempsAsSubModelOutputs; 121c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // Outputs of original model that are inputs of this submodel: 122c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // (fromModel index, subModel index) 123c4c264098a728268ad28084ea6e0263d9c1d7868David Gross RemapVectorType mOutputsAsSubModelInputs; 12491e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet // Converts operand indexes from the main model to the submodel. 12591e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet std::unordered_map<uint32_t, uint32_t> mOperandMap; 126891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross // Converts input indexes from the submodel to the main model 127891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross // (these are input indexes, not operand indexes). This vector 128891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross // only describes inputs of the submodel that are also inputs of 129c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // the main model -- that is, mModelInputs but not mTempsAsSubModelInputs. 130891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross std::vector<uint32_t> mInputIndexSubModelToFromModel; 131891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross // Converts output indexes from the submodel to the main model 132891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross // (these are output indexes, not operand indexes). This vector 133891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross // only describes outputs of the submodel that are also outputs of 134c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // the main model -- that is, mModelOutputs but not mTempsAsSubModelOutputs. 135891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross std::vector<uint32_t> mOutputIndexSubModelToFromModel; 136c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // Converts indexes into mOutputsAsSubModelInputs to indexes into 137c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // main model outputs (these are input and output indexes, not 138c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // operand indexes). To be specific, if the main model outputs 139c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // are mainModelOutputs, 140c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // 141c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // mOutputsAsSubModelInputsIndexToFromModel.size() == 142c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // mOutputsAsSubModelInputs.size() 143c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // 144c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // and when (0 <= i < mOutputsAsSubModelInputs.size()), 145c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // 146c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // mainModelOutputs[mOutputsAsSubModelInputsIndexToFromModel[i]] == 147c4c264098a728268ad28084ea6e0263d9c1d7868David Gross // mOutputsAsSubModelInputs[i].first 148c4c264098a728268ad28084ea6e0263d9c1d7868David Gross std::vector<uint32_t> mOutputsAsSubModelInputsIndexToFromModel; 14991e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet}; 15091e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet 15191e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletclass ExecutionPlan { 1528913ae3283de7752aed108c1b26aef1adacb049fDavid Grosspublic: 1531f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross ExecutionPlan(const ExecutionPlan&) = delete; 1541f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross ExecutionPlan& operator=(const ExecutionPlan&) = delete; 1558913ae3283de7752aed108c1b26aef1adacb049fDavid Gross 1561f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross ExecutionPlan() { } 1571f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross ~ExecutionPlan() { delete mBody; } 1581f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross 159b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // Controller is part of the interface to a mechanism for 160b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // performing an execution in N steps. 161b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // 162b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // Usage pattern: 163b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // - Instantiate Controller with ExecutionPlan::makeController(). 164b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // - Call ExecutionPlan::next() on Controller N+1 times. The first N times, 165b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // *executor is set to point to a new StepExecutor corresponding 166b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // to that step. The N+1st time, *executor is set to nullptr, 167b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // signifying there are no more steps. 168b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // - If ExecutionPlan::next() returns anything other than ANEURALNETWORKS_NO_ERROR, 169b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross // a problem has occurred. 170b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross class Controller { 171b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross friend class ExecutionPlan; 172b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross private: 173a2a03635c8f215cb75be68ff1939bf4dec285ef8David Gross Controller(const Controller&) = delete; 174a2a03635c8f215cb75be68ff1939bf4dec285ef8David Gross Controller& operator=(const Controller&) = delete; 175a2a03635c8f215cb75be68ff1939bf4dec285ef8David Gross 17696811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross // Map from the operand index of a TEMPORARY in the original 1778fb14e90ceb360adfbac0f708d27161b7c5b7fc5David Gross // model to an offset into mTemporaries used to represent that 1788fb14e90ceb360adfbac0f708d27161b7c5b7fc5David Gross // TEMPORARY as an inter-partition input or output. 1798fb14e90ceb360adfbac0f708d27161b7c5b7fc5David Gross typedef std::map<uint32_t, uint32_t> SubModelInputsAndOutputsType; 18096811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross 181b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross static const size_t kBadStepIndex = ~size_t(0); 182b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross 18396811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross Controller(const ExecutionPlan* plan, const ExecutionBuilder* executionBuilder, 1848fb14e90ceb360adfbac0f708d27161b7c5b7fc5David Gross std::shared_ptr<const SubModelInputsAndOutputsType> subModelInputsAndOutputs, 1858fb14e90ceb360adfbac0f708d27161b7c5b7fc5David Gross uint32_t totalSizeOfTemporaries); 186b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross 187a2a03635c8f215cb75be68ff1939bf4dec285ef8David Gross const ExecutionPlan* mPlan; 188a2a03635c8f215cb75be68ff1939bf4dec285ef8David Gross const ExecutionBuilder* mExecutionBuilder; 18996811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross std::shared_ptr<const SubModelInputsAndOutputsType> mSubModelInputsAndOutputs; // may be nullptr 1908fb14e90ceb360adfbac0f708d27161b7c5b7fc5David Gross Memory mTemporaries; 191a2a03635c8f215cb75be68ff1939bf4dec285ef8David Gross size_t mNextStepIndex; 192b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross }; 193b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross 194a2a03635c8f215cb75be68ff1939bf4dec285ef8David Gross std::shared_ptr<Controller> makeController(const ExecutionBuilder* executionBuilder) const; 195b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross 196a2a03635c8f215cb75be68ff1939bf4dec285ef8David Gross int next(std::shared_ptr<Controller> controller, std::shared_ptr<StepExecutor>* executor) const; 197b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross 1985e8feed5e8a07bab1ec395e5a01bb8900db00cecDavid Gross // Create the same executor as the last one created by next(). 1995e8feed5e8a07bab1ec395e5a01bb8900db00cecDavid Gross int fallback(std::shared_ptr<Controller> controller, std::shared_ptr<StepExecutor>* executor) const; 2005e8feed5e8a07bab1ec395e5a01bb8900db00cecDavid Gross 2011f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross std::shared_ptr<ExecutionStep> createNewStep(const std::shared_ptr<Device> device); 2021f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross 2031f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross void becomeSingleStep(const std::shared_ptr<Device> device, 2041f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross const ModelBuilder* model); 2051f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross 206891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross int finish(const ModelBuilder* fromModel); 2078913ae3283de7752aed108c1b26aef1adacb049fDavid Gross 2088913ae3283de7752aed108c1b26aef1adacb049fDavid Gross void recordTemporaryDef(uint32_t fromModelIndex, uint32_t stepIndex) { 2091f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross auto& temporaryToDefiningStep = compound()->mTemporaryToDefiningStep; 2101f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross nnAssert(temporaryToDefiningStep.count(fromModelIndex) == 0); 2111f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross temporaryToDefiningStep.insert(std::make_pair(fromModelIndex, stepIndex)); 21291e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet } 2138913ae3283de7752aed108c1b26aef1adacb049fDavid Gross 2148913ae3283de7752aed108c1b26aef1adacb049fDavid Gross void dump() const; 2158913ae3283de7752aed108c1b26aef1adacb049fDavid Gross 216def0a14aa77689f12120cfb4f136eea659038cc0David Gross // These functions are solely intended for use by unit tests of 217def0a14aa77689f12120cfb4f136eea659038cc0David Gross // the partitioning algorithm. 218def0a14aa77689f12120cfb4f136eea659038cc0David Gross enum class Kind { ERROR, EMPTY, SIMPLE, COMPOUND }; 219def0a14aa77689f12120cfb4f136eea659038cc0David Gross Kind forTest_getKind() const; 220def0a14aa77689f12120cfb4f136eea659038cc0David Gross std::shared_ptr<const Device> forTest_simpleGetDevice() const; 221def0a14aa77689f12120cfb4f136eea659038cc0David Gross const std::vector<std::shared_ptr<ExecutionStep>>& forTest_compoundGetSteps() const; 222def0a14aa77689f12120cfb4f136eea659038cc0David Gross 2238913ae3283de7752aed108c1b26aef1adacb049fDavid Grossprivate: 224c4c264098a728268ad28084ea6e0263d9c1d7868David Gross void findTempsAsSubModelOutputs(); 2258913ae3283de7752aed108c1b26aef1adacb049fDavid Gross 2261f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross struct Body { 2271f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross virtual ~Body() {} 2281f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross virtual void dump() const = 0; 229891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross virtual int finish(const ModelBuilder* fromModel) = 0; 230891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross bool mSuccessfulFinish = false; 2311f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross }; 2321f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross 2331f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross struct SimpleBody : Body { 2341f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross SimpleBody(std::shared_ptr<Device> device, const ModelBuilder* model) : 2351f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross mDevice(device), mModel(model) {} 2368913ae3283de7752aed108c1b26aef1adacb049fDavid Gross 2371f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross void dump() const override; 238891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross int finish(const ModelBuilder* fromModel) override; 2398913ae3283de7752aed108c1b26aef1adacb049fDavid Gross 2401f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross std::shared_ptr<Device> mDevice; // nullptr signifies CPU 2411f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross const ModelBuilder* mModel; 2421f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross sp<IPreparedModel> mPreparedModel; // not used for CPU 2431f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross }; 2441f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross 2451f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross struct CompoundBody : Body { 2461f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross void dump() const override; 247891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross int finish(const ModelBuilder* fromModel) override; 2481f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross 2491f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross // TODO: Some of the data is working state information that 2501f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross // shouldn't be needed after we've constructed but not 2511f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross // executed the plan. 2521f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross 2531f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross std::vector<std::shared_ptr<ExecutionStep>> mSteps; 2541f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross 2551f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross // Map from original operand index to defining step index. 2561f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross // Used for all (and only) TEMPORARY_VARIABLEs. 2571f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross std::unordered_map<uint32_t, uint32_t> mTemporaryToDefiningStep; 2581f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross 259891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross bool mHasSubModelOutputOfUnknownSize = false; 2601f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross private: 261c4c264098a728268ad28084ea6e0263d9c1d7868David Gross void findTempsAsSubModelOutputs(); 2621f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross }; 2631f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross 2641f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross enum { EMPTY, SIMPLE, COMPOUND } mState = EMPTY; 2651f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross Body* mBody = nullptr; 2661f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross CompoundBody* compound() { 2671f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross nnAssert(mState == COMPOUND); 2681f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross return static_cast<CompoundBody*>(mBody); 2691f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross } 27096811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross const CompoundBody* compound() const { 27196811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross nnAssert(mState == COMPOUND); 27296811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross return static_cast<const CompoundBody*>(mBody); 27396811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross } 27491e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet}; 27591e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet 27691e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet} // namespace nn 27791e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet} // namespace android 27891e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet 27991e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet#endif // ANDROID_ML_NN_RUNTIME_EXECUTION_PLAN_H 280