0db9b6133d8b4ca6528a57d32f190915d828f1b9
[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)
60 {
61   assert(isBuildingPhase());
62   _inputs.append(ind);
63 }
64
65 void Graph::addOutput(const OperandIndex &ind)
66 {
67   assert(isBuildingPhase());
68   _outputs.append(ind);
69 }
70
71 void Graph::finishBuilding(void)
72 {
73   assert(isBuildingPhase());
74   _phase = Phase::MODEL;
75
76   initializeUseDef();
77   sweepGarbageOperands();
78
79   // Call graph verifications for the MODEL phase
80   {
81     assert(verifier::DAGChecker().verify(*this));
82     assert(verifier::EdgeConsistencyChecker().verify(*this));
83   }
84 }
85
86 void Graph::initializeUseDef()
87 {
88   operations().iterate([&](const OperationIndex &index, const Operation &node) -> void {
89     auto outputs = node.getOutputs();
90     for (auto output : outputs)
91     {
92       operands().at(output).setDef(index);
93     }
94
95     for (auto input : node.getInputs() | ir::Remove::UNDEFINED)
96     {
97       operands().at(input).insertUse(index);
98     }
99   });
100 }
101
102 void Graph::sweepGarbageOperands()
103 {
104   // Remove operands that are not used by any operations, except Graph inputs/outputs
105   ir::OperandIndexMap<bool> visited;
106
107   operations().iterate([&](const OperationIndex &, const Operation &node) {
108     for (auto ind : node.getInputs() + node.getOutputs())
109     {
110       visited[ind] = true;
111     }
112   });
113
114   // Graph's inputs/outputs are always reachable
115   for (auto ind : getInputs() + getOutputs())
116   {
117     visited[ind] = true;
118   }
119
120   operands().iterate([&](const OperandIndex &ind, const Operand &) {
121     if (!visited[ind])
122     {
123       VERBOSE(Graph::sweepGarbageOperands) << "Sweep garbage operand " << ind.value() << std::endl;
124       operands().remove(ind);
125     }
126   });
127 }
128
129 } // namespace ir
130 } // namespace onert