Imported Upstream version 1.21.0
[platform/core/ml/nnfw.git] / runtime / onert / core / src / interp / InterpExecutor.cc
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "InterpExecutor.h"
18
19 #include "ExecEnv.h"
20 #include "Interpreter.h"
21
22 #include "util/logging.h"
23
24 #include <memory>
25
26 namespace onert
27 {
28 namespace interp
29 {
30
31 void InterpExecutor::execute(const exec::IODescription &desc)
32 {
33   /************************************************************************
34    * Prepare execution model (submodel)
35      It may execute divided model
36      but now consider model inference is done at interpreter
37    ***********************************************************************/
38   ir::OperandIndexMap<std::shared_ptr<ITensor>> tensor_map;
39
40   for (uint32_t n = 0; n < _graph.getInputs().size(); n++)
41   {
42     ir::IOIndex index{n};
43     const auto input_index = _graph.getInputs().at(index);
44
45     const auto input = desc.inputs.at(n).get();
46     if (input == nullptr)
47     {
48       // Optional input
49       continue;
50     }
51
52     auto input_tensor = std::make_shared<ROTensor>(input->info);
53     input_tensor->setData(std::make_shared<const ir::ExternalData>(
54       reinterpret_cast<const uint8_t *>(input->buffer), input->size));
55     tensor_map[input_index] = input_tensor;
56   }
57
58   /************************************************************************
59    * Prepare execution environment
60      Execution environment will be assigned to invoked interpreter instance
61    ***********************************************************************/
62
63   std::unique_ptr<ExecEnv> interp_env = std::make_unique<ExecEnv>(_graph);
64
65   // Assign input/output tensor into interpreter execution environment
66   for (auto index : _graph.getInputs())
67   {
68     if (tensor_map.find(index) != tensor_map.end())
69     {
70       VERBOSE(INTERPRETER) << "Assign input tensor. operand index:" << index << std::endl;
71       interp_env->assignTensor(index, tensor_map.at(index));
72     }
73   }
74
75   for (uint32_t n = 0; n < _graph.getOutputs().size(); n++)
76   {
77     ir::IOIndex index{n};
78     const auto output_index = _graph.getOutputs().at(index);
79     const auto output = desc.outputs.at(n).get();
80     if (output == nullptr)
81     {
82       // Optional output
83       continue;
84     }
85
86     VERBOSE(INTERPRETER) << "Set out buffer to ExecEnv. operand index:" << output_index.value()
87                          << std::endl;
88
89     interp_env->assignExternalBuffer(
90       output_index,
91       std::make_shared<ExternalBuffer>(reinterpret_cast<uint8_t *>(output->buffer), output->size));
92   }
93
94   // Allocate constant tensor
95   _graph.operands().iterate([&](const ir::OperandIndex &ind, const ir::Operand &obj) {
96     if (obj.isConstant())
97     {
98       VERBOSE(INTERPRETER) << "Allocate and assign constant tensor. operand index:" << ind
99                            << std::endl;
100
101       assert(obj.data());
102       auto const_tensor = std::make_shared<ROTensor>(obj.info());
103       // Assume that interpreter's tensor layout is same with model (NHWC)
104       const_tensor->setData(
105         std::make_shared<ir::ExternalData>(obj.data()->base(), obj.info().total_size()));
106       interp_env->assignTensor(ind, const_tensor);
107     }
108   });
109
110   /*****************************************************************************
111    * Invoke interpreter
112    ****************************************************************************/
113
114   interp::Interpreter interp(std::move(interp_env));
115   interp.run();
116
117   /*****************************************************************************
118    * Invoked interpreter run is finished
119    ****************************************************************************/
120
121   // If interpreter execute submodel
122   //  1. Get tensor output of submodel into tensor_map to save result
123   //  2. Generate new ExecEnv for next interpretation
124 }
125
126 } // namespace interp
127 } // namespace onert