ExecutionPlan.h revision a2a03635c8f215cb75be68ff1939bf4dec285ef8
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"
2491e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet#include "NeuralNetworks.h"
2591e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet#include "Utils.h"
2691e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet
278913ae3283de7752aed108c1b26aef1adacb049fDavid Gross#include <set>
288913ae3283de7752aed108c1b26aef1adacb049fDavid Gross
2991e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletnamespace android {
3091e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletnamespace nn {
3191e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet
3291e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletclass CompilationBuilder;
3391e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletclass Device;
34b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Grossclass ExecutionBuilder;
358913ae3283de7752aed108c1b26aef1adacb049fDavid Grossclass ExecutionPlan;
3691e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletclass Memory;
3791e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletclass ModelBuilder;
38b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Grossclass StepExecutor;
3991e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet
4091e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletclass ExecutionStep {
418913ae3283de7752aed108c1b26aef1adacb049fDavid Grossprivate:
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
4591e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletpublic:
46f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross    enum OperandKind { INPUT, OUTPUT };
47f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross
488913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    ExecutionStep(ExecutionPlan* plan,
498913ae3283de7752aed108c1b26aef1adacb049fDavid Gross                  uint32_t stepIndex,
508913ae3283de7752aed108c1b26aef1adacb049fDavid Gross                  std::shared_ptr<ModelBuilder> model,
518913ae3283de7752aed108c1b26aef1adacb049fDavid Gross                  std::shared_ptr<Device> device);
5291e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet    int addOperation(int operationIndex, const ModelBuilder& fromModel);
5391e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet    int addOperand(uint32_t fromOperandIndex, uint32_t* toOperandIndex,
54f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross                   const ModelBuilder& fromModel, OperandKind kind);
5591e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet
5696811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross    // Each container entry is of the form (fromModel index, subModel index)
5796811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross    const RemapVectorType& getModelInputs() const {
5896811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross        return mModelInputs;
5996811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross    }
6096811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross    const RemapVectorType& getModelOutputs() const {
6196811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross        return mModelOutputs;
6296811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross    }
638913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    const RemapVectorType& getSubModelInputs() const {
648913ae3283de7752aed108c1b26aef1adacb049fDavid Gross        return mSubModelInputs;
658913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    }
6696811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross    const SubModelOutputSetType& getSubModelOutputs() const {
6796811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross        return mSubModelOutputs;
6896811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross    }
69b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross
708913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    void recordSubModelOutput(uint32_t fromModelIndex) {
718913ae3283de7752aed108c1b26aef1adacb049fDavid Gross        const auto it = mOperandMap.find(fromModelIndex);
728913ae3283de7752aed108c1b26aef1adacb049fDavid Gross        nnAssert(it != mOperandMap.end());
738913ae3283de7752aed108c1b26aef1adacb049fDavid Gross        mSubModelOutputs.insert(std::make_pair(fromModelIndex, it->second));
748913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    }
758913ae3283de7752aed108c1b26aef1adacb049fDavid Gross
76b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    // If this step has a submodel output of unknown size, sets
77b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    // *hasOutputOfUnknownSize to true; otherwise, leaves it
78b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    // unchanged.
79891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    int finishSubModel(const ModelBuilder* fromModel, bool* hasOutputOfUnknownSize);
80891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross
81891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    std::shared_ptr<ModelBuilder> getSubModel() const { return mSubModel; }
82891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    std::shared_ptr<Device> getDevice() const { return mDevice; }
83891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross
84891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    // only available after calling finishSubModel()
85891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    sp<IPreparedModel> getPreparedSubModel() const { return mPreparedSubModel; }
86891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross
87891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    // Map inputs and outputs from ExecutionBuilder to StepExecutor.
88891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    void mapInputsAndOutputs(std::shared_ptr<StepExecutor> stepExecutor) const;
898913ae3283de7752aed108c1b26aef1adacb049fDavid Gross
908913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    void dump() const;
9191e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletprivate:
92f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross    // TODO: Some of the data is working state information that
93f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross    // shouldn't be needed after we've constructed but not executed
94f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross    // the step.
95f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross
968913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    ExecutionPlan* mPlan;
978913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    uint32_t mIndex;  // index of step within plan
9891e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet    std::shared_ptr<ModelBuilder> mSubModel;
998913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    std::shared_ptr<Device> mDevice;  // nullptr signifies CPU
1001f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    sp<IPreparedModel> mPreparedSubModel;  // not used for CPU
101f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross
102f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross    // Inputs of original model that are also inputs of this submodel:
103f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross    //     (fromModel index, subModel index)
1048913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    RemapVectorType mModelInputs;
105f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross    // Outputs of original model that are also outputs of this submodel:
106f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross    //     (fromModel index, subModel index)
1078913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    RemapVectorType mModelOutputs;
108f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross    // Temporaries of original model that are inputs of this submodel:
109f4e1c640547a44c7a37209e81ee5f3831b7d0fdcDavid Gross    //     (fromModel index, subModel index)
1108913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    RemapVectorType mSubModelInputs;
1118913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    // Temporaries of original model that are outputs of this submodel:
1128913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    //     (fromModel index, subModel index)
113b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    SubModelOutputSetType mSubModelOutputs;
11491e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet    // Converts operand indexes from the main model to the submodel.
11591e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet    std::unordered_map<uint32_t, uint32_t> mOperandMap;
116891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    // Converts input indexes from the submodel to the main model
117891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    // (these are input indexes, not operand indexes).  This vector
118891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    // only describes inputs of the submodel that are also inputs of
119891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    // the main model -- that is, mModelInputs but not mSubModelInputs.
120891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    std::vector<uint32_t> mInputIndexSubModelToFromModel;
121891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    // Converts output indexes from the submodel to the main model
122891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    // (these are output indexes, not operand indexes).  This vector
123891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    // only describes outputs of the submodel that are also outputs of
124891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    // the main model -- that is, mModelOutputs but not mSubModelOutputs.
125891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    std::vector<uint32_t> mOutputIndexSubModelToFromModel;
12691e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet};
12791e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet
12891e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouilletclass ExecutionPlan {
1298913ae3283de7752aed108c1b26aef1adacb049fDavid Grosspublic:
1301f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    ExecutionPlan(const ExecutionPlan&) = delete;
1311f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    ExecutionPlan& operator=(const ExecutionPlan&) = delete;
1328913ae3283de7752aed108c1b26aef1adacb049fDavid Gross
1331f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    ExecutionPlan() { }
1341f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    ~ExecutionPlan() { delete mBody; }
1351f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross
136b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    // Controller is part of the interface to a mechanism for
137b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    // performing an execution in N steps.
138b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    //
139b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    // Usage pattern:
140b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    // - Instantiate Controller with ExecutionPlan::makeController().
141b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    // - Call ExecutionPlan::next() on Controller N+1 times.  The first N times,
142b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    //   *executor is set to point to a new StepExecutor corresponding
143b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    //   to that step.  The N+1st time, *executor is set to nullptr,
144b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    //   signifying there are no more steps.
145b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    // - If ExecutionPlan::next() returns anything other than ANEURALNETWORKS_NO_ERROR,
146b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    //   a problem has occurred.
147b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    class Controller {
148b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross        friend class ExecutionPlan;
149b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    private:
150a2a03635c8f215cb75be68ff1939bf4dec285ef8David Gross        Controller(const Controller&) = delete;
151a2a03635c8f215cb75be68ff1939bf4dec285ef8David Gross        Controller& operator=(const Controller&) = delete;
152a2a03635c8f215cb75be68ff1939bf4dec285ef8David Gross
15396811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross        // Map from the operand index of a TEMPORARY in the original
15496811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross        // model to a Memory object used to represent that TEMPORARY
15596811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross        // as an inter-partition input or output.
15696811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross        typedef std::map<uint32_t, Memory> SubModelInputsAndOutputsType;
15796811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross
158b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross        static const size_t kBadStepIndex = ~size_t(0);
159b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross
16096811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross        Controller(const ExecutionPlan* plan, const ExecutionBuilder* executionBuilder,
16196811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross                   std::shared_ptr<const SubModelInputsAndOutputsType> subModelInputsAndOutputs) :
16296811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross                mPlan(plan), mExecutionBuilder(executionBuilder),
16396811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross                mSubModelInputsAndOutputs(subModelInputsAndOutputs), mNextStepIndex(0) {}
164b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross
165a2a03635c8f215cb75be68ff1939bf4dec285ef8David Gross        const ExecutionPlan* mPlan;
166a2a03635c8f215cb75be68ff1939bf4dec285ef8David Gross        const ExecutionBuilder* mExecutionBuilder;
16796811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross        std::shared_ptr<const SubModelInputsAndOutputsType> mSubModelInputsAndOutputs;  // may be nullptr
168a2a03635c8f215cb75be68ff1939bf4dec285ef8David Gross        size_t mNextStepIndex;
169b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross    };
170b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross
171a2a03635c8f215cb75be68ff1939bf4dec285ef8David Gross    std::shared_ptr<Controller> makeController(const ExecutionBuilder* executionBuilder) const;
172b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross
173a2a03635c8f215cb75be68ff1939bf4dec285ef8David Gross    int next(std::shared_ptr<Controller> controller, std::shared_ptr<StepExecutor>* executor) const;
174b26049114bc4c64e6bea3a5d5d129fcaec8e69b6David Gross
1751f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    std::shared_ptr<ExecutionStep> createNewStep(const std::shared_ptr<Device> device);
1761f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross
1771f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    void becomeSingleStep(const std::shared_ptr<Device> device,
1781f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross                          const ModelBuilder* model);
1791f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross
180891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross    int finish(const ModelBuilder* fromModel);
1818913ae3283de7752aed108c1b26aef1adacb049fDavid Gross
1828913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    void recordTemporaryDef(uint32_t fromModelIndex, uint32_t stepIndex) {
1831f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        auto& temporaryToDefiningStep = compound()->mTemporaryToDefiningStep;
1841f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        nnAssert(temporaryToDefiningStep.count(fromModelIndex) == 0);
1851f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        temporaryToDefiningStep.insert(std::make_pair(fromModelIndex, stepIndex));
18691e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet    }
1878913ae3283de7752aed108c1b26aef1adacb049fDavid Gross
1888913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    void dump() const;
1898913ae3283de7752aed108c1b26aef1adacb049fDavid Gross
1908913ae3283de7752aed108c1b26aef1adacb049fDavid Grossprivate:
1918913ae3283de7752aed108c1b26aef1adacb049fDavid Gross    void findSubModelOutputs();
1928913ae3283de7752aed108c1b26aef1adacb049fDavid Gross
1931f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    struct Body {
1941f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        virtual ~Body() {}
1951f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        virtual void dump() const = 0;
196891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross        virtual int finish(const ModelBuilder* fromModel) = 0;
197891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross        bool mSuccessfulFinish = false;
1981f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    };
1991f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross
2001f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    struct SimpleBody : Body {
2011f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        SimpleBody(std::shared_ptr<Device> device, const ModelBuilder* model) :
2021f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross                mDevice(device), mModel(model) {}
2038913ae3283de7752aed108c1b26aef1adacb049fDavid Gross
2041f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        void dump() const override;
205891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross        int finish(const ModelBuilder* fromModel) override;
2068913ae3283de7752aed108c1b26aef1adacb049fDavid Gross
2071f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        std::shared_ptr<Device> mDevice;  // nullptr signifies CPU
2081f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        const ModelBuilder* mModel;
2091f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        sp<IPreparedModel> mPreparedModel;  // not used for CPU
2101f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    };
2111f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross
2121f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    struct CompoundBody : Body {
2131f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        void dump() const override;
214891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross        int finish(const ModelBuilder* fromModel) override;
2151f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross
2161f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        // TODO: Some of the data is working state information that
2171f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        // shouldn't be needed after we've constructed but not
2181f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        // executed the plan.
2191f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross
2201f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        std::vector<std::shared_ptr<ExecutionStep>> mSteps;
2211f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross
2221f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        // Map from original operand index to defining step index.
2231f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        // Used for all (and only) TEMPORARY_VARIABLEs.
2241f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        std::unordered_map<uint32_t, uint32_t> mTemporaryToDefiningStep;
2251f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross
226891b10f7048c62a37a74c4b570be220089dfd55eDavid Gross        bool mHasSubModelOutputOfUnknownSize = false;
2271f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    private:
2281f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        void findSubModelOutputs();
2291f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    };
2301f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross
2311f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    enum { EMPTY, SIMPLE, COMPOUND } mState = EMPTY;
2321f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    Body* mBody = nullptr;
2331f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    CompoundBody* compound() {
2341f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        nnAssert(mState == COMPOUND);
2351f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross        return static_cast<CompoundBody*>(mBody);
2361f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross    }
23796811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross    const CompoundBody* compound() const {
23896811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross        nnAssert(mState == COMPOUND);
23996811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross        return static_cast<const CompoundBody*>(mBody);
24096811e2b1347889a25bd9686f47ca3cbf061fb1bDavid Gross    }
24191e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet};
24291e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet
24391e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet}  // namespace nn
24491e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet}  // namespace android
24591e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet
24691e8417c4c395e3922d12abfd956b93b71121976Jean-Luc Brouillet#endif  // ANDROID_ML_NN_RUNTIME_EXECUTION_PLAN_H
247