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;
40 INTERNAL_EXN_V("trying to convert unsupported luci::FusedActFunc", oops::to_uint32(func));
44 circle::TensorType to_circle_tensortype(loco::DataType type)
48 case loco::DataType::U8:
49 return circle::TensorType_UINT8;
51 case loco::DataType::S8:
52 return circle::TensorType_INT8;
53 case loco::DataType::S16:
54 return circle::TensorType_INT16;
55 case loco::DataType::S32:
56 return circle::TensorType_INT32;
57 case loco::DataType::S64:
58 return circle::TensorType_INT64;
60 case loco::DataType::FLOAT16:
61 return circle::TensorType_FLOAT16;
62 case loco::DataType::FLOAT32:
63 return circle::TensorType_FLOAT32;
65 case loco::DataType::BOOL:
66 return circle::TensorType_BOOL;
69 INTERNAL_EXN_V("failed to convert unsupported loco::DataType", oops::to_uint32(type));
73 circle::MirrorPadMode to_circle_mirrorpadmode(luci::MirrorPadMode mode)
77 case luci::MirrorPadMode::REFLECT:
78 return circle::MirrorPadMode::MirrorPadMode_REFLECT;
79 case luci::MirrorPadMode::SYMMETRIC:
80 return circle::MirrorPadMode::MirrorPadMode_SYMMETRIC;
82 INTERNAL_EXN_V("trying to convert unsupported luci::MirrorPadMode", oops::to_uint32(mode));
91 uint32_t SerializedModelData::registerBuiltinOpcode(circle::BuiltinOperator builtin_code,
92 const int32_t op_version)
94 assert(op_version > 0);
96 auto it = _operator_codes.find(OpCode{builtin_code, "", op_version});
97 if (it != _operator_codes.end())
101 auto idx = static_cast<uint32_t>(_operator_codes.size());
102 _operator_codes.emplace(OpCode{builtin_code, "", op_version}, idx);
106 uint32_t SerializedModelData::registerCustomOpcode(const std::string &custom_code)
108 const circle::BuiltinOperator builtin_code = circle::BuiltinOperator_CUSTOM;
109 auto it = _operator_codes.find(OpCode{builtin_code, custom_code});
110 if (it != _operator_codes.end())
114 auto idx = static_cast<uint32_t>(_operator_codes.size());
115 _operator_codes.emplace(OpCode{builtin_code, custom_code}, idx);
119 circle::Padding getOpPadding(const loco::Padding2D *pad, const loco::Stride<2> *stride,
120 const ShapeDescription &ifm, const ShapeDescription &ofm)
123 if (pad->top() == 0 && pad->bottom() == 0 && pad->left() == 0 && pad->right() == 0)
124 return circle::Padding_VALID;
128 // For same padding, by definition, following equation should hold:
129 // O = floor((I - 1) / S) + 1
130 // where input size I, output size O, stride S
132 // NOTE input and output 'feature' map are shape of NHWC
133 bool same_padding_criterion_1 =
134 (static_cast<uint32_t>(ofm._dims[1]) == (ifm._dims[1] - 1) / stride->vertical() + 1) &&
135 (static_cast<uint32_t>(ofm._dims[2]) == (ifm._dims[2] - 1) / stride->horizontal() + 1);
137 // For same padding, rear padding is same or bigger than front padding by at most 1
138 bool same_padding_criterion_2 =
139 (pad->top() <= pad->bottom()) && (pad->bottom() <= pad->top() + 1) &&
140 (pad->left() <= pad->right()) && (pad->right() <= pad->left() + 1);
142 if (same_padding_criterion_1 && same_padding_criterion_2)
143 return circle::Padding_SAME;
145 INTERNAL_EXN("Unsupported padding criteria");
148 circle::Padding getOpPadding(const luci::Padding pad)
150 if (pad == luci::Padding::VALID)
151 return circle::Padding_VALID;
152 if (pad == luci::Padding::SAME)
153 return circle::Padding_SAME;
155 INTERNAL_EXN_V("Unsupported luci::Padding", oops::to_uint32(pad));
161 class CircleTensorIndexAnnotation final : public loco::NodeAnnotation
164 CircleTensorIndexAnnotation(const CircleTensorIndex &index) : _index{index}
170 const CircleTensorIndex &index(void) const { return _index; }
173 CircleTensorIndex _index;
178 void set_tensor_index(loco::Node *node, const CircleTensorIndex &tensor_id)
180 assert(node->annot<CircleTensorIndexAnnotation>() == nullptr);
181 node->annot(std::make_unique<CircleTensorIndexAnnotation>(tensor_id));
184 CircleTensorIndex get_tensor_index(loco::Node *node)
186 assert(node->annot<CircleTensorIndexAnnotation>() != nullptr);
187 return node->annot<CircleTensorIndexAnnotation>()->index();