Imported Upstream version 1.9.0
[platform/core/ml/nnfw.git] / runtime / onert / core / src / ir / Graph.cc
1 /*
2  * Copyright (c) 2018 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 "ir/Graph.h"
18
19 #include <algorithm>
20 #include <bitset>
21 #include <sstream>
22
23 #include "util/logging.h"
24 #include "verifier/Verifier.h"
25 #include "ir/operation/LowerInfo.h"
26 #include "ir/operand/LowerInfo.h"
27 #include "ir/operand/PermuteFactor.h"
28 #include "ir/OperandIndexMap.h"
29 #include "ir/GraphIterator.h"
30 #include "backend/IConfig.h"
31
32 namespace onert
33 {
34 namespace ir
35 {
36
37 Graph::Graph() = default;
38
39 Graph::~Graph(void) = default;
40
41 OperandIndex Graph::addOperand(const Shape &shape, const TypeInfo &type)
42 {
43   return _operands.emplace(shape, type);
44 }
45
46 OperationIndex Graph::addOperation(std::unique_ptr<Operation> &&node)
47 {
48   assert(isBuildingPhase());
49   return _operations.push(std::move(node));
50 }
51
52 void Graph::setOperandValue(const OperandIndex &ind, std::shared_ptr<Data> data)
53 {
54   assert(isBuildingPhase());
55   assert(_operands.exist(ind));
56   _operands.at(ind).data(std::move(data));
57 }
58
59 void Graph::addInput(const OperandIndex &ind, const std::string &name)
60 {
61   assert(isBuildingPhase());
62   if (!name.empty())
63     _name_to_input.emplace(name, IOIndex{_inputs.size()});
64   _inputs.append(ind);
65 }
66
67 void Graph::addOutput(const OperandIndex &ind, const std::string &name)
68 {
69   assert(isBuildingPhase());
70   if (!name.empty())
71     _name_to_output.emplace(name, IOIndex{_outputs.size()});
72   _outputs.append(ind);
73 }
74
75 IOIndex Graph::getInputIndex(const std::string &name) const
76 {
77   auto itr = _name_to_input.find(name);
78   return (itr == _name_to_input.end()) ? IOIndex{} : itr->second;
79 }
80
81 IOIndex Graph::getOutputIndex(const std::string &name) const
82 {
83   auto itr = _name_to_output.find(name);
84   return (itr == _name_to_output.end()) ? IOIndex{} : itr->second;
85 }
86
87 void Graph::finishBuilding(void)
88 {
89   assert(isBuildingPhase());
90   _phase = Phase::MODEL;
91
92   initializeUseDef();
93   sweepGarbageOperands();
94
95   // Call graph verifications for the MODEL phase
96   {
97     assert(verifier::DAGChecker().verify(*this));
98     assert(verifier::EdgeConsistencyChecker().verify(*this));
99   }
100 }
101
102 void Graph::initializeUseDef()
103 {
104   operations().iterate([&](const OperationIndex &index, const Operation &node) -> void {
105     auto outputs = node.getOutputs();
106     for (auto output : outputs)
107     {
108       operands().at(output).setDef(index);
109     }
110
111     for (auto input : node.getInputs() | ir::Remove::UNDEFINED)
112     {
113       operands().at(input).insertUse(index);
114     }
115   });
116 }
117
118 void Graph::sweepGarbageOperands()
119 {
120   // Remove operands that are not used by any operations, except Graph inputs/outputs
121   ir::OperandIndexMap<bool> visited;
122
123   operations().iterate([&](const OperationIndex &, const Operation &node) {
124     for (auto ind : node.getInputs() + node.getOutputs())
125     {
126       visited[ind] = true;
127     }
128   });
129
130   // Graph's inputs/outputs are always reachable
131   for (auto ind : getInputs() + getOutputs())
132   {
133     visited[ind] = true;
134   }
135
136   operands().iterate([&](const OperandIndex &ind, const Operand &) {
137     if (!visited[ind])
138     {
139       VERBOSE(Graph::sweepGarbageOperands) << "Sweep garbage operand " << ind.value() << std::endl;
140       operands().remove(ind);
141     }
142   });
143 }
144
145 } // namespace ir
146 } // namespace onert