ONE - On-device Neural Engine
Loading...
Searching...
No Matches
CircleExporterUtils.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 "CircleExporterUtils.h"
18
19#include <oops/InternalExn.h>
20
21namespace exo
22{
23
24circle::ActivationFunctionType to_circle_actfunc(locoex::FusedActFunc func)
25{
26 switch (func)
27 {
29 return circle::ActivationFunctionType_NONE;
31 return circle::ActivationFunctionType_RELU;
33 return circle::ActivationFunctionType_RELU6;
34 default:
35 INTERNAL_EXN_V("trying to convert unsupported locoex::FusedActFunc", oops::to_uint32(func));
36 }
37}
38
39} // namespace exo
40
41namespace exo
42{
43namespace circle_detail
44{
45
46uint32_t SerializedModelData::registerBuiltinOpcode(circle::BuiltinOperator builtin_code)
47{
48 auto it = _operator_codes.find(OpCode{builtin_code});
49 if (it != _operator_codes.end())
50 {
51 return it->second;
52 }
53 auto idx = static_cast<uint32_t>(_operator_codes.size());
54 _operator_codes.emplace(OpCode{builtin_code}, idx);
55 return idx;
56}
57
58uint32_t SerializedModelData::registerCustomOpcode(const std::string &custom_op)
59{
60 circle::BuiltinOperator custom_code = circle::BuiltinOperator_CUSTOM;
61 auto idx = registerBuiltinOpcode(custom_code);
62 _custom_operator_codes.emplace(OpCode{custom_code}, custom_op);
63 return idx;
64}
65
66circle::Padding getOpPadding(const loco::Padding2D *pad, const loco::Stride<2> *stride,
67 const ShapeDescription &ifm, const ShapeDescription &ofm)
68{
69 // VALID padding
70 if (pad->top() == 0 && pad->bottom() == 0 && pad->left() == 0 && pad->right() == 0)
71 return circle::Padding_VALID;
72
73 // SAME padding
74 //
75 // For same padding, by definition, following equation should hold:
76 // O = floor((I - 1) / S) + 1
77 // where input size I, output size O, stride S
78 //
79 // NOTE input and output 'feature' map are shape of NHWC
80 bool same_padding_criterion_1 =
81 (static_cast<uint32_t>(ofm._dims[1]) == (ifm._dims[1] - 1) / stride->vertical() + 1) &&
82 (static_cast<uint32_t>(ofm._dims[2]) == (ifm._dims[2] - 1) / stride->horizontal() + 1);
83
84 // For same padding, rear padding is same or bigger than front padding by at most 1
85 bool same_padding_criterion_2 =
86 (pad->top() <= pad->bottom()) && (pad->bottom() <= pad->top() + 1) &&
87 (pad->left() <= pad->right()) && (pad->right() <= pad->left() + 1);
88
89 if (same_padding_criterion_1 && same_padding_criterion_2)
90 return circle::Padding_SAME;
91
92 INTERNAL_EXN("Unsupported padding criteria");
93}
94
95circle::Padding getOpPadding(const locoex::Padding pad)
96{
97 if (pad == locoex::Padding::VALID)
98 return circle::Padding_VALID;
99 if (pad == locoex::Padding::SAME)
100 return circle::Padding_SAME;
101
102 INTERNAL_EXN_V("Unsupported locoex::Padding", oops::to_uint32(pad));
103}
104
106{
107 for (uint32_t in = 0; in < graph->inputs()->size(); ++in)
108 {
109 auto pull = loco::pull_node(graph, in);
110 auto name = graph->inputs()->at(in)->name();
111
112 gd._pull_to_name[pull] = name;
113 }
114 for (uint32_t out = 0; out < graph->outputs()->size(); ++out)
115 {
116 auto push = loco::push_node(graph, out);
117 auto name = graph->outputs()->at(out)->name();
118
119 gd._push_to_name[push] = name;
120 }
121
122 // TODO set this value properly
123 gd._data_format = circle::DataFormat::DataFormat_CHANNELS_LAST;
124}
125
126#include <memory>
127#include <cassert>
128
129namespace
130{
131
132class TFLTensorIndexAnnotation final : public loco::NodeAnnotation
133{
134public:
135 TFLTensorIndexAnnotation(const TFLTensorIndex &index) : _index{index}
136 {
137 // DO NOTHING
138 }
139
140public:
141 const TFLTensorIndex &index(void) const { return _index; }
142
143private:
144 TFLTensorIndex _index;
145};
146
147} // namespace
148
149void set_tensor_index(loco::Node *node, const TFLTensorIndex &tensor_id)
150{
151 assert(node->annot<TFLTensorIndexAnnotation>() == nullptr);
152 node->annot(std::make_unique<TFLTensorIndexAnnotation>(tensor_id));
153}
154
156{
157 assert(node->annot<TFLTensorIndexAnnotation>() != nullptr);
158 return node->annot<TFLTensorIndexAnnotation>()->index();
159}
160
161} // namespace circle_detail
162} // namespace exo
#define INTERNAL_EXN(msg)
@ brief throw internal exception with message
Definition InternalExn.h:25
#define INTERNAL_EXN_V(msg, val)
@ brief throw internal exception with message and value
Definition InternalExn.h:28
const T * annot(void) const
Retrieve a stored annotation of type T.
A neural network graph.
Definition Graph.h:161
Logical unit of computation.
Definition Node.h:54
uint32_t left(void) const
Definition Padding2D.h:49
uint32_t top(void) const
Definition Padding2D.h:41
uint32_t bottom(void) const
Definition Padding2D.h:45
uint32_t right(void) const
Definition Padding2D.h:53
Stride configuration for N-dimensional spatial operations.
Definition Stride.h:28
void registerGraphIOName(loco::Graph *graph, SerializedModelData &gd)
Register graph input and output names to SerializedModelData.
circle::Padding getOpPadding(const loco::Padding2D *pad, const loco::Stride< 2 > *stride, const ShapeDescription &ifm, const ShapeDescription &ofm)
TFLTensorIndex get_tensor_index(loco::Node *node)
void set_tensor_index(loco::Node *node, const TFLTensorIndex &tensor_id)
circle::ActivationFunctionType to_circle_actfunc(locoex::FusedActFunc func)
Pull * pull_node(Graph *g, const GraphInputIndex &index)
Find a Pull node with a given input index.
Definition Nodes.cpp:162
Push * push_node(Graph *g, const GraphOutputIndex &index)
Find a Push node with a given output index.
Definition Nodes.cpp:67
uint32_t to_uint32(T a)
Definition InternalExn.h:33
int32_t size[5]
Definition Slice.cpp:35
std::vector< int32_t > _dims
uint32_t registerBuiltinOpcode(circle::BuiltinOperator builtin_code)
if opcode is not registered in table of opcodes add it
std::unordered_map< loco::Pull *, std::string > _pull_to_name
std::unordered_map< OpCode, std::string > _custom_operator_codes
std::unordered_map< loco::Push *, std::string > _push_to_name
std::unordered_map< OpCode, uint32_t > _operator_codes
uint32_t registerCustomOpcode(const std::string &custom_op)
circle::DataFormat _data_format
@DataFormat for SubGraph
Extensible Node Metadata.
Definition Node.h:39