ONE - On-device Neural Engine
Loading...
Searching...
No Matches
Dump.cpp
Go to the documentation of this file.
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 "Dump.h"
18
19#include <mio_circle/Helper.h>
20#include <mio_circle/Reader.h>
21
22#include <ostream>
23
25{
26
27void DumpOperators::run(std::ostream &os, const circle::Model *model, const std::vector<char> *data)
28{
29 mio::circle::Reader reader(model, data);
30
31 const uint32_t subgraph_size = reader.num_subgraph();
32
33 for (uint32_t g = 0; g < subgraph_size; g++)
34 {
35 reader.select_subgraph(g);
36 auto ops = reader.operators();
37
38 // dump operators
39 for (uint32_t i = 0; i < ops->size(); ++i)
40 {
41 const auto op = ops->Get(i);
42
43 auto op_name = reader.opcode_name(op);
44
45 os << op_name << std::endl;
46 }
47 }
48}
49
50} // namespace circleinspect
51
52namespace
53{
54
55const circle::Operator *operator_match_output(mio::circle::Reader &reader, const int32_t tensor)
56{
57 auto ops = reader.operators();
58
59 for (uint32_t i = 0; i < ops->size(); ++i)
60 {
61 const auto op = ops->Get(i);
62
63 const std::vector<int32_t> &outputs = mio::circle::as_index_vector(op->outputs());
64
65 for (auto output : outputs)
66 {
67 if (output == tensor)
68 return op;
69 }
70 }
71 return nullptr;
72}
73
74size_t tensor_buffer_size(mio::circle::Reader &reader, const int32_t tensor_id)
75{
76 auto tensors = reader.tensors();
77
78 if (tensor_id < 0 || tensor_id >= tensors->size())
79 {
80 throw std::runtime_error("Invalid Tensor ID");
81 }
82
83 auto tensor = tensors->Get(tensor_id);
84 auto buffer_id = tensor->buffer();
85 bool ext_offset = false;
86
87 size_t size = reader.buffer_info(buffer_id, nullptr, ext_offset);
88
89 return size;
90}
91
92} // namespace
93
94namespace circleinspect
95{
96
97void DumpConv2DWeight::run(std::ostream &os, const circle::Model *model,
98 const std::vector<char> *data)
99{
100 mio::circle::Reader reader(model, data);
101
102 const uint32_t subgraph_size = reader.num_subgraph();
103
104 for (uint32_t g = 0; g < subgraph_size; g++)
105 {
106 reader.select_subgraph(g);
107 auto ops = reader.operators();
108
109 // dump Conv2D, DepthwiseConv2D and its weight input operator
110 for (uint32_t i = 0; i < ops->size(); ++i)
111 {
112 const auto op = ops->Get(i);
113 auto bc = reader.builtin_code(op);
114
115 if (bc == circle::BuiltinOperator_CONV_2D || bc == circle::BuiltinOperator_DEPTHWISE_CONV_2D)
116 {
117 const std::vector<int32_t> &inputs = mio::circle::as_index_vector(op->inputs());
118 if (inputs.size() < 2)
119 {
120 throw std::runtime_error("Operator has invalid input");
121 }
122 auto weight_input = inputs[1]; // Tensor ID of weight input
123
124 const auto op_weight = operator_match_output(reader, weight_input);
125 const auto buffer_size = tensor_buffer_size(reader, weight_input);
126
127 std::string weight_op_name = "?";
128
129 if (op_weight == nullptr && buffer_size > 0)
130 {
131 weight_op_name = "CONST";
132 }
133 else if (op_weight != nullptr)
134 {
135 weight_op_name = reader.opcode_name(op_weight);
136 }
137
138 auto op_name = reader.opcode_name(op);
139 os << op_name << "," << weight_op_name << std::endl;
140 }
141 }
142 }
143}
144
145} // namespace circleinspect
146
147namespace circleinspect
148{
149
150void DumpOperatorVersion::run(std::ostream &os, const circle::Model *model,
151 const std::vector<char> *data)
152{
153 std::map<std::string, int32_t> op_version_map;
154
155 mio::circle::Reader reader(model, data);
156
157 // This assert is subject to be changed later
158 assert(reader.num_subgraph() == 1);
159 reader.select_subgraph(0);
160
161 auto ops = reader.operators();
162
163 // Dump operators' version
164 for (uint32_t i = 0; i < ops->size(); ++i)
165 {
166 const auto op = ops->Get(i);
167
168 auto op_name = reader.opcode_name(op);
169 auto op_version = reader.opcodes().at(op->opcode_index())->version();
170
171 if (op_version_map.find(op_name) == op_version_map.end() ||
172 op_version_map[op_name] < op_version)
173 op_version_map[op_name] = op_version;
174 }
175
176 for (auto op : op_version_map)
177 {
178 os << op.first << "," << op.second << std::endl;
179 }
180}
181
182} // namespace circleinspect
183
184namespace circleinspect
185{
186
187void DumpTensorDType::run(std::ostream &os, const circle::Model *model,
188 const std::vector<char> *data)
189{
190 mio::circle::Reader reader(model, data);
191
192 const uint32_t subgraph_size = reader.num_subgraph();
193
194 for (uint32_t g = 0; g < subgraph_size; g++)
195 {
196 reader.select_subgraph(g);
197 auto tensors = reader.tensors();
198
199 for (uint32_t i = 0; i < tensors->size(); ++i)
200 {
201 const auto tensor = tensors->Get(i);
202
203 os << reader.tensor_name(tensor) << " " << reader.tensor_dtype(tensor) << std::endl;
204 }
205 }
206}
207
208} // namespace circleinspect
209
210namespace circleinspect
211{
212
213void DumpConstants::run(std::ostream &os, const circle::Model *model, const std::vector<char> *data)
214{
215 mio::circle::Reader reader(model, data);
216
217 const uint32_t subgraph_size = reader.num_subgraph();
218
219 for (uint32_t g = 0; g < subgraph_size; g++)
220 {
221 reader.select_subgraph(g);
222 auto tensors = reader.tensors();
223
224 for (uint32_t i = 0; i < tensors->size(); ++i)
225 {
226 const auto tensor = tensors->Get(i);
227 if (tensor->is_variable())
228 continue;
229
230 auto const buffer_id = tensor->buffer();
231 bool ext_offset = false;
232
233 auto const buffer_size = reader.buffer_info(buffer_id, nullptr, ext_offset);
234 if (buffer_size == 0)
235 continue;
236
237 os << reader.tensor_name(tensor) << std::endl;
238 }
239 }
240}
241
242} // namespace circleinspect
243
244namespace circleinspect
245{
246
247void DumpTensorShape::run(std::ostream &os, const circle::Model *model,
248 const std::vector<char> *data)
249{
250 mio::circle::Reader reader(model, data);
251
252 const uint32_t subgraph_size = reader.num_subgraph();
253
254 for (uint32_t g = 0; g < subgraph_size; g++)
255 {
256 reader.select_subgraph(g);
257 auto tensors = reader.tensors();
258
259 for (uint32_t i = 0; i < tensors->size(); ++i)
260 {
261 const auto tensor = tensors->Get(i);
262 auto shape = tensor->shape_signature() ? tensor->shape_signature() : tensor->shape();
263 os << reader.tensor_name(tensor) << " [";
264 for (uint32_t i = 0; i < shape->size(); i++)
265 {
266 os << shape->Get(i);
267 if (i != shape->size() - 1)
268 {
269 os << ",";
270 }
271 }
272 os << "]" << std::endl;
273 }
274 }
275}
276
277} // namespace circleinspect
void run(std::ostream &os, const circle::Model *model, const std::vector< char > *data)
Definition Dump.cpp:213
void run(std::ostream &os, const circle::Model *model, const std::vector< char > *data)
Definition Dump.cpp:97
void run(std::ostream &os, const circle::Model *model, const std::vector< char > *data)
Definition Dump.cpp:150
void run(std::ostream &os, const circle::Model *model, const std::vector< char > *data)
Definition Dump.cpp:27
void run(std::ostream &os, const circle::Model *model, const std::vector< char > *data)
Definition Dump.cpp:187
void run(std::ostream &os, const circle::Model *model, const std::vector< char > *data)
Definition Dump.cpp:247
Loads Circle file and provides helpers to access attributes.
Definition Reader.h:39
const std::vector< const ::circle::OperatorCode * > & opcodes()
Definition Reader.h:56
const CircleTensors_t * tensors()
Definition Reader.h:58
std::string opcode_name(const ::circle::Operator *op) const
Definition Reader.cpp:85
uint32_t num_subgraph() const
Definition Reader.h:66
const CircleOperators_t * operators()
Definition Reader.h:59
std::string tensor_name(const ::circle::Tensor *tensor) const
Definition Reader.cpp:106
size_t buffer_info(uint32_t buf_idx, const uint8_t **buff_data)
Definition Reader.cpp:48
std::string tensor_dtype(const ::circle::Tensor *tensor) const
Definition Reader.cpp:111
::circle::BuiltinOperator builtin_code(const ::circle::Operator *op) const
Definition Reader.cpp:76
bool select_subgraph(uint32_t subgraph)
Definition Reader.cpp:116
std::vector< T > as_index_vector(const flatbuffers::Vector< T > *flat_array)
Definition Helper.h:36
int32_t size[5]
Definition Slice.cpp:35