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#include "Reader.h"
19
20#include <string>
21#include <ostream>
22#include <stdexcept>
23
24namespace tflinspect
25{
26
27void DumpOperators::run(std::ostream &os, const tflite::Model *model)
28{
29 tflinspect::Reader reader(model);
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 tflinspect
51
52namespace
53{
54
55const tflite::Operator *operator_match_output(tflinspect::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 = tflinspect::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(tflinspect::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
86 size_t size = reader.buffer_info(buffer_id, nullptr);
87
88 return size;
89}
90
91} // namespace
92
93namespace tflinspect
94{
95
96void DumpConv2DWeight::run(std::ostream &os, const tflite::Model *model)
97{
98 tflinspect::Reader reader(model);
99
100 const uint32_t subgraph_size = reader.num_subgraph();
101
102 for (uint32_t g = 0; g < subgraph_size; g++)
103 {
104 reader.select_subgraph(g);
105 auto ops = reader.operators();
106
107 // dump Conv2D, DepthwiseConv2D and its weight input operator
108 for (uint32_t i = 0; i < ops->size(); ++i)
109 {
110 const auto op = ops->Get(i);
111 auto bc = reader.builtin_code(op);
112
113 if (bc == tflite::BuiltinOperator_CONV_2D || bc == tflite::BuiltinOperator_DEPTHWISE_CONV_2D)
114 {
115 const std::vector<int32_t> &inputs = tflinspect::as_index_vector(op->inputs());
116 if (inputs.size() < 2)
117 {
118 throw std::runtime_error("Operator has invalid input");
119 }
120 auto weight_input = inputs[1]; // Tensor ID of weight input
121
122 const auto op_weight = operator_match_output(reader, weight_input);
123 const auto buffer_size = tensor_buffer_size(reader, weight_input);
124
125 std::string weight_op_name = "?";
126
127 if (op_weight == nullptr && buffer_size > 0)
128 {
129 weight_op_name = "CONST";
130 }
131 else if (op_weight != nullptr)
132 {
133 weight_op_name = reader.opcode_name(op_weight);
134 }
135
136 auto op_name = reader.opcode_name(op);
137 os << op_name << "," << weight_op_name << std::endl;
138 }
139 }
140 }
141}
142
143} // namespace tflinspect
144
145namespace tflinspect
146{
147
148void DumpOperatorVersion::run(std::ostream &os, const tflite::Model *model)
149{
150 std::map<std::string, int32_t> op_version_map;
151
152 tflinspect::Reader reader(model);
153
154 const uint32_t subgraph_size = reader.num_subgraph();
155
156 for (uint32_t g = 0; g < subgraph_size; g++)
157 {
158 reader.select_subgraph(g);
159 auto ops = reader.operators();
160
161 // dump Conv2D, DepthwiseConv2D and its weight input operator
162 for (uint32_t i = 0; i < ops->size(); ++i)
163 {
164 const auto op = ops->Get(i);
165
166 auto op_name = reader.opcode_name(op);
167 auto op_version = reader.opcodes().at(op->opcode_index())->version();
168
169 if (op_version_map.find(op_name) == op_version_map.end() ||
170 op_version_map[op_name] < op_version)
171 op_version_map[op_name] = op_version;
172 }
173 }
174
175 for (auto op : op_version_map)
176 {
177 os << op.first << "," << op.second << std::endl;
178 }
179}
180
181} // namespace tflinspect
void run(std::ostream &os, const tflite::Model *model)
Definition Dump.cpp:96
void run(std::ostream &os, const tflite::Model *model)
Definition Dump.cpp:148
void run(std::ostream &os, const tflite::Model *model)
Definition Dump.cpp:27
Loads TF lite file and provides helpers to access attributes.
Definition Reader.h:43
bool select_subgraph(uint32_t subgraph)
Definition Reader.cpp:93
const TFliteOperators_t * operators()
Definition Reader.h:59
tflite::BuiltinOperator builtin_code(const tflite::Operator *op) const
Definition Reader.cpp:68
const TFliteTensors_t * tensors()
Definition Reader.h:58
uint32_t num_subgraph() const
Definition Reader.h:63
size_t buffer_info(uint32_t buf_idx, const uint8_t **buff_data)
Definition Reader.cpp:40
const std::vector< const tflite::OperatorCode * > & opcodes()
Definition Reader.h:56
std::string opcode_name(const tflite::Operator *op) const
Definition Reader.cpp:77
std::vector< T > as_index_vector(const flatbuffers::Vector< T > *flat_array)
Definition Reader.h:29
int32_t size[5]
Definition Slice.cpp:35
This file contains Reader class.