2 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "CircleExporterUtils.h"
19 #include <oops/InternalExn.h>
27 circle::ActivationFunctionType to_circle_actfunc(luci::FusedActFunc func)
31 case luci::FusedActFunc::NONE:
32 return circle::ActivationFunctionType_NONE;
33 case luci::FusedActFunc::RELU:
34 return circle::ActivationFunctionType_RELU;
35 case luci::FusedActFunc::RELU_N1_TO_1:
36 return circle::ActivationFunctionType_RELU_N1_TO_1;
37 case luci::FusedActFunc::RELU6:
38 return circle::ActivationFunctionType_RELU6;
39 case luci::FusedActFunc::TANH:
40 return circle::ActivationFunctionType_TANH;
41 case luci::FusedActFunc::SIGN_BIT:
42 return circle::ActivationFunctionType_SIGN_BIT;
44 INTERNAL_EXN_V("trying to convert unsupported luci::FusedActFunc", oops::to_uint32(func));
48 circle::TensorType to_circle_tensortype(loco::DataType type)
52 case loco::DataType::U8:
53 return circle::TensorType_UINT8;
55 case loco::DataType::S8:
56 return circle::TensorType_INT8;
57 case loco::DataType::S16:
58 return circle::TensorType_INT16;
59 case loco::DataType::S32:
60 return circle::TensorType_INT32;
61 case loco::DataType::S64:
62 return circle::TensorType_INT64;
64 case loco::DataType::FLOAT16:
65 return circle::TensorType_FLOAT16;
66 case loco::DataType::FLOAT32:
67 return circle::TensorType_FLOAT32;
69 case loco::DataType::BOOL:
70 return circle::TensorType_BOOL;
73 INTERNAL_EXN_V("failed to convert unsupported loco::DataType", oops::to_uint32(type));
77 circle::MirrorPadMode to_circle_mirrorpadmode(luci::MirrorPadMode mode)
81 case luci::MirrorPadMode::REFLECT:
82 return circle::MirrorPadMode::MirrorPadMode_REFLECT;
83 case luci::MirrorPadMode::SYMMETRIC:
84 return circle::MirrorPadMode::MirrorPadMode_SYMMETRIC;
86 INTERNAL_EXN_V("trying to convert unsupported luci::MirrorPadMode", oops::to_uint32(mode));
90 circle::DimensionType to_circle_dimensiontype(luci::DimensionType type)
94 case luci::DimensionType::DENSE:
95 return circle::DimensionType_DENSE;
96 case luci::DimensionType::SPARSE_CSR:
97 return circle::DimensionType_SPARSE_CSR;
99 INTERNAL_EXN_V("trying to convert unsupported luci::DimensionType", oops::to_uint32(type));
103 flatbuffers::Offset<void> to_circle_sparse_index_vector(flatbuffers::FlatBufferBuilder &fb,
104 const SparseIndexVector &sparse_idx_vec)
106 auto type = sparse_idx_vec.type();
109 case luci::SparseIndexVectorType::NONE:
110 return flatbuffers::Offset<void>();
111 case luci::SparseIndexVectorType::I32:
113 return circle::CreateInt32VectorDirect(fb, sparse_idx_vec.as_int32_vector()).Union();
115 case luci::SparseIndexVectorType::U16:
117 return circle::CreateUint16VectorDirect(fb, sparse_idx_vec.as_uint16_vector()).Union();
119 case luci::SparseIndexVectorType::U8:
121 return circle::CreateUint8VectorDirect(fb, sparse_idx_vec.as_uint8_vector()).Union();
124 INTERNAL_EXN_V("trying to convert unsupported luci::SparseIndexVectorType",
125 oops::to_uint32(type));
129 circle::SparseIndexVector to_circle_sparse_index_vector_type(luci::SparseIndexVectorType type)
133 case luci::SparseIndexVectorType::NONE:
134 return circle::SparseIndexVector_NONE;
135 case luci::SparseIndexVectorType::I32:
136 return circle::SparseIndexVector_Int32Vector;
137 case luci::SparseIndexVectorType::U16:
138 return circle::SparseIndexVector_Uint16Vector;
139 case luci::SparseIndexVectorType::U8:
140 return circle::SparseIndexVector_Uint8Vector;
142 INTERNAL_EXN_V("trying to convert unsupported luci::SparseIndexVectorType",
143 oops::to_uint32(type));
152 uint32_t SerializedModelData::registerBuiltinOpcode(circle::BuiltinOperator builtin_code,
153 const int32_t op_version)
155 assert(op_version > 0);
157 auto it = _operator_codes.find(OpCode{builtin_code, "", op_version});
158 if (it != _operator_codes.end())
162 auto idx = static_cast<uint32_t>(_operator_codes.size());
163 _operator_codes.emplace(OpCode{builtin_code, "", op_version}, idx);
167 uint32_t SerializedModelData::registerCustomOpcode(const std::string &custom_code)
169 const circle::BuiltinOperator builtin_code = circle::BuiltinOperator_CUSTOM;
170 auto it = _operator_codes.find(OpCode{builtin_code, custom_code});
171 if (it != _operator_codes.end())
175 auto idx = static_cast<uint32_t>(_operator_codes.size());
176 _operator_codes.emplace(OpCode{builtin_code, custom_code}, idx);
180 circle::Padding getOpPadding(const loco::Padding2D *pad, const loco::Stride<2> *stride,
181 const ShapeDescription &ifm, const ShapeDescription &ofm)
184 if (pad->top() == 0 && pad->bottom() == 0 && pad->left() == 0 && pad->right() == 0)
185 return circle::Padding_VALID;
189 // For same padding, by definition, following equation should hold:
190 // O = floor((I - 1) / S) + 1
191 // where input size I, output size O, stride S
193 // NOTE input and output 'feature' map are shape of NHWC
194 bool same_padding_criterion_1 =
195 (static_cast<uint32_t>(ofm._dims[1]) == (ifm._dims[1] - 1) / stride->vertical() + 1) &&
196 (static_cast<uint32_t>(ofm._dims[2]) == (ifm._dims[2] - 1) / stride->horizontal() + 1);
198 // For same padding, rear padding is same or bigger than front padding by at most 1
199 bool same_padding_criterion_2 =
200 (pad->top() <= pad->bottom()) && (pad->bottom() <= pad->top() + 1) &&
201 (pad->left() <= pad->right()) && (pad->right() <= pad->left() + 1);
203 if (same_padding_criterion_1 && same_padding_criterion_2)
204 return circle::Padding_SAME;
206 INTERNAL_EXN("Unsupported padding criteria");
209 circle::Padding getOpPadding(const luci::Padding pad)
211 if (pad == luci::Padding::VALID)
212 return circle::Padding_VALID;
213 if (pad == luci::Padding::SAME)
214 return circle::Padding_SAME;
216 INTERNAL_EXN_V("Unsupported luci::Padding", oops::to_uint32(pad));
222 class CircleTensorIndexAnnotation final : public loco::NodeAnnotation
225 CircleTensorIndexAnnotation(const CircleTensorIndex &index) : _index{index}
231 const CircleTensorIndex &index(void) const { return _index; }
234 CircleTensorIndex _index;
239 void set_tensor_index(loco::Node *node, const CircleTensorIndex &tensor_id)
241 assert(node->annot<CircleTensorIndexAnnotation>() == nullptr);
242 node->annot(std::make_unique<CircleTensorIndexAnnotation>(tensor_id));
245 CircleTensorIndex get_tensor_index(loco::Node *node)
247 assert(node->annot<CircleTensorIndexAnnotation>() != nullptr);
248 return node->annot<CircleTensorIndexAnnotation>()->index();