2 * Copyright (c) 2021 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 #ifndef __CIRCLE_BUILTIN_TYPES_EXTRACTOR_H__
18 #define __CIRCLE_BUILTIN_TYPES_EXTRACTOR_H__
20 #include "CircleExporterUtils.h"
22 #include <luci/IR/CircleNode.h>
23 #include <luci/IR/CircleNodes.h>
24 #include <luci/IR/CircleNodeVisitor.h>
26 #include <flatbuffers/flexbuffers.h>
31 // NOTE Virtual nodes are not circle builtin operators.
32 // Therefore, they are not defined here.
33 class BuiltinOptionsExtractor final
34 : public luci::CircleNodeMutableVisitor<flatbuffers::Offset<void>>
37 BuiltinOptionsExtractor(flatbuffers::FlatBufferBuilder &builder) : _builder{builder}
43 flatbuffers::Offset<void> visit(luci::CircleAbs *)
45 return circle::CreateAbsOptions(_builder).Union();
47 flatbuffers::Offset<void> visit(luci::CircleAdd *node)
49 return circle::CreateAddOptions(_builder, to_circle_actfunc(node->fusedActivationFunction()))
52 flatbuffers::Offset<void> visit(luci::CircleAddN *)
54 return circle::CreateAddNOptions(_builder).Union();
56 flatbuffers::Offset<void> visit(luci::CircleArgMax *node)
58 return circle::CreateArgMaxOptions(_builder, luci::to_circle_tensortype(node->output_type()))
61 flatbuffers::Offset<void> visit(luci::CircleArgMin *node)
63 return circle::CreateArgMinOptions(_builder, luci::to_circle_tensortype(node->output_type()))
66 flatbuffers::Offset<void> visit(luci::CircleAveragePool2D *node)
68 return circle::CreatePool2DOptions(_builder, getOpPadding(node->padding()), node->stride()->w(),
69 node->stride()->h(), node->filter()->w(),
71 to_circle_actfunc(node->fusedActivationFunction()))
74 flatbuffers::Offset<void> visit(luci::CircleBatchMatMul *node)
76 return circle::CreateBatchMatMulOptions(_builder, node->adj_x(), node->adj_y()).Union();
78 flatbuffers::Offset<void> visit(luci::CircleBatchToSpaceND *)
80 return circle::CreateBatchToSpaceNDOptions(_builder).Union();
82 flatbuffers::Offset<void> visit(luci::CircleBidirectionalSequenceLSTM *node)
84 return circle::CreateBidirectionalSequenceLSTMOptions(
85 _builder, to_circle_actfunc(node->fusedActivationFunction()), node->cell_clip(),
86 node->proj_clip(), node->merge_outputs(), node->time_major(),
87 node->asymmetric_quantize_inputs())
90 flatbuffers::Offset<void> visit(luci::CircleCast *node)
92 if (node->out_data_type() == loco::DataType::Unknown)
95 return circle::CreateCastOptions(_builder, luci::to_circle_tensortype(node->in_data_type()),
96 luci::to_circle_tensortype(node->out_data_type()))
99 flatbuffers::Offset<void> visit(luci::CircleCeil *) { return _no_option; }
100 flatbuffers::Offset<void> visit(luci::CircleConcatenation *node)
102 return circle::CreateConcatenationOptions(_builder, node->axis(),
103 to_circle_actfunc(node->fusedActivationFunction()))
106 // CircleConst is not virtual but not builtinOperator
107 // flatbuffers::Offset<void> visit(luci::CircleConst *)
108 flatbuffers::Offset<void> visit(luci::CircleConv2D *node)
110 return circle::CreateConv2DOptions(_builder, getOpPadding(node->padding()), node->stride()->w(),
112 to_circle_actfunc(node->fusedActivationFunction()),
113 node->dilation()->w(), node->dilation()->h())
116 flatbuffers::Offset<void> visit(luci::CircleCos *)
118 return circle::CreateCosOptions(_builder).Union();
120 flatbuffers::Offset<void> visit(luci::CircleCustom *) { return _no_option; }
121 flatbuffers::Offset<void> visit(luci::CircleDensify *)
123 return circle::CreateDensifyOptions(_builder).Union();
125 flatbuffers::Offset<void> visit(luci::CircleDepthToSpace *node)
127 return circle::CreateDepthToSpaceOptions(_builder, node->block_size()).Union();
129 flatbuffers::Offset<void> visit(luci::CircleDepthwiseConv2D *node)
131 return circle::CreateDepthwiseConv2DOptions(
132 _builder, getOpPadding(node->padding()), node->stride()->w(), node->stride()->h(),
133 node->depthMultiplier(), to_circle_actfunc(node->fusedActivationFunction()),
134 node->dilation()->w(), node->dilation()->h())
137 flatbuffers::Offset<void> visit(luci::CircleDequantize *) { return _no_option; }
138 flatbuffers::Offset<void> visit(luci::CircleDiv *node)
140 return circle::CreateDivOptions(_builder, to_circle_actfunc(node->fusedActivationFunction()))
143 flatbuffers::Offset<void> visit(luci::CircleElu *) { return _no_option; }
144 flatbuffers::Offset<void> visit(luci::CircleEqual *)
146 return circle::CreateEqualOptions(_builder).Union();
148 flatbuffers::Offset<void> visit(luci::CircleExp *)
150 return circle::CreateExpOptions(_builder).Union();
152 flatbuffers::Offset<void> visit(luci::CircleExpandDims *)
154 return circle::CreateExpandDimsOptions(_builder).Union();
156 flatbuffers::Offset<void> visit(luci::CircleFakeQuant *node)
158 return circle::CreateFakeQuantOptions(_builder, node->min(), node->max(), node->num_bits(),
159 node->narrow_range())
162 flatbuffers::Offset<void> visit(luci::CircleFill *)
164 return circle::CreateFillOptions(_builder).Union();
166 flatbuffers::Offset<void> visit(luci::CircleFloor *) { return _no_option; }
167 flatbuffers::Offset<void> visit(luci::CircleFloorDiv *)
169 return circle::CreateFloorDivOptions(_builder).Union();
171 flatbuffers::Offset<void> visit(luci::CircleFloorMod *)
173 return circle::CreateFloorModOptions(_builder).Union();
175 flatbuffers::Offset<void> visit(luci::CircleFullyConnected *node)
177 return circle::CreateFullyConnectedOptions(
178 _builder, to_circle_actfunc(node->fusedActivationFunction()),
179 to_circle_weightsformat(node->weights_format()), node->keep_num_dims())
182 flatbuffers::Offset<void> visit(luci::CircleGather *node)
184 return circle::CreateGatherOptions(_builder, node->axis()).Union();
186 flatbuffers::Offset<void> visit(luci::CircleGatherNd *)
188 return circle::CreateGatherNdOptions(_builder).Union();
190 flatbuffers::Offset<void> visit(luci::CircleGreater *)
192 return circle::CreateGreaterOptions(_builder).Union();
194 flatbuffers::Offset<void> visit(luci::CircleGreaterEqual *)
196 return circle::CreateGreaterEqualOptions(_builder).Union();
198 flatbuffers::Offset<void> visit(luci::CircleIf *node)
200 return circle::CreateIfOptions(_builder, node->then_branch(), node->else_branch()).Union();
202 flatbuffers::Offset<void> visit(luci::CircleL2Normalize *node)
204 return circle::CreateL2NormOptions(_builder, to_circle_actfunc(node->fusedActivationFunction()))
207 flatbuffers::Offset<void> visit(luci::CircleL2Pool2D *node)
209 return circle::CreatePool2DOptions(_builder, getOpPadding(node->padding()), node->stride()->w(),
210 node->stride()->h(), node->filter()->w(),
212 to_circle_actfunc(node->fusedActivationFunction()))
215 flatbuffers::Offset<void> visit(luci::CircleLeakyRelu *node)
217 return circle::CreateLeakyReluOptions(_builder, node->alpha()).Union();
219 flatbuffers::Offset<void> visit(luci::CircleLess *)
221 return circle::CreateLessOptions(_builder).Union();
223 flatbuffers::Offset<void> visit(luci::CircleLessEqual *)
225 return circle::CreateLessEqualOptions(_builder).Union();
227 flatbuffers::Offset<void> visit(luci::CircleLocalResponseNormalization *node)
229 return circle::CreateLocalResponseNormalizationOptions(_builder, node->radius(), node->bias(),
230 node->alpha(), node->beta())
233 flatbuffers::Offset<void> visit(luci::CircleLog *) { return _no_option; }
234 flatbuffers::Offset<void> visit(luci::CircleLogicalAnd *)
236 return circle::CreateLogicalAndOptions(_builder).Union();
238 flatbuffers::Offset<void> visit(luci::CircleLogicalNot *)
240 return circle::CreateLogicalNotOptions(_builder).Union();
242 flatbuffers::Offset<void> visit(luci::CircleLogicalOr *)
244 return circle::CreateLogicalOrOptions(_builder).Union();
246 flatbuffers::Offset<void> visit(luci::CircleLogistic *) { return _no_option; }
247 flatbuffers::Offset<void> visit(luci::CircleLogSoftmax *)
249 return circle::CreateLogSoftmaxOptions(_builder).Union();
251 flatbuffers::Offset<void> visit(luci::CircleMatrixDiag *)
253 return circle::CreateMatrixDiagOptions(_builder).Union();
255 flatbuffers::Offset<void> visit(luci::CircleMatrixSetDiag *)
257 return circle::CreateMatrixSetDiagOptions(_builder).Union();
259 flatbuffers::Offset<void> visit(luci::CircleMaximum *)
261 return circle::CreateMaximumMinimumOptions(_builder).Union();
263 flatbuffers::Offset<void> visit(luci::CircleMaxPool2D *node)
265 return circle::CreatePool2DOptions(_builder, getOpPadding(node->padding()), node->stride()->w(),
266 node->stride()->h(), node->filter()->w(),
268 to_circle_actfunc(node->fusedActivationFunction()))
271 flatbuffers::Offset<void> visit(luci::CircleMean *node)
273 return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
275 flatbuffers::Offset<void> visit(luci::CircleMinimum *)
277 return circle::CreateMaximumMinimumOptions(_builder).Union();
279 flatbuffers::Offset<void> visit(luci::CircleMirrorPad *node)
281 return circle::CreateMirrorPadOptions(_builder, to_circle_mirrorpadmode(node->mode())).Union();
283 flatbuffers::Offset<void> visit(luci::CircleMul *node)
285 return circle::CreateMulOptions(_builder, to_circle_actfunc(node->fusedActivationFunction()))
288 flatbuffers::Offset<void> visit(luci::CircleNeg *)
290 return circle::CreateNegOptions(_builder).Union();
292 flatbuffers::Offset<void> visit(luci::CircleNonMaxSuppressionV4 *)
294 return circle::CreateNonMaxSuppressionV4Options(_builder).Union();
296 flatbuffers::Offset<void> visit(luci::CircleNonMaxSuppressionV5 *)
298 return circle::CreateNonMaxSuppressionV5Options(_builder).Union();
300 flatbuffers::Offset<void> visit(luci::CircleNotEqual *)
302 return circle::CreateNotEqualOptions(_builder).Union();
304 flatbuffers::Offset<void> visit(luci::CircleOneHot *node)
306 return circle::CreateOneHotOptions(_builder, node->axis()).Union();
308 flatbuffers::Offset<void> visit(luci::CirclePack *node)
310 return circle::CreatePackOptions(_builder, node->values_count(), node->axis()).Union();
312 flatbuffers::Offset<void> visit(luci::CirclePad *)
314 return circle::CreatePadOptions(_builder).Union();
316 flatbuffers::Offset<void> visit(luci::CirclePadV2 *)
318 return circle::CreatePadV2Options(_builder).Union();
320 flatbuffers::Offset<void> visit(luci::CirclePow *)
322 return circle::CreatePowOptions(_builder).Union();
324 flatbuffers::Offset<void> visit(luci::CirclePRelu *) { return _no_option; }
325 flatbuffers::Offset<void> visit(luci::CircleQuantize *) { return _no_option; }
326 flatbuffers::Offset<void> visit(luci::CircleRange *)
328 return circle::CreateRangeOptions(_builder).Union();
330 flatbuffers::Offset<void> visit(luci::CircleRank *)
332 return circle::CreateRankOptions(_builder).Union();
334 flatbuffers::Offset<void> visit(luci::CircleReduceAny *node)
336 return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
338 flatbuffers::Offset<void> visit(luci::CircleReduceMax *node)
340 return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
342 flatbuffers::Offset<void> visit(luci::CircleReduceMin *node)
344 return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
346 flatbuffers::Offset<void> visit(luci::CircleReduceProd *node)
348 return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
350 flatbuffers::Offset<void> visit(luci::CircleRelu *) { return _no_option; }
351 flatbuffers::Offset<void> visit(luci::CircleRelu6 *) { return _no_option; }
352 flatbuffers::Offset<void> visit(luci::CircleReluN1To1 *) { return _no_option; }
353 flatbuffers::Offset<void> visit(luci::CircleReshape *node)
355 auto new_shape = _builder.CreateVector<int32_t>(
356 node->newShape()->rank(), [node](size_t i) { return node->newShape()->dim(i); });
357 return circle::CreateReshapeOptions(_builder, new_shape).Union();
359 flatbuffers::Offset<void> visit(luci::CircleResizeBilinear *node)
361 return circle::CreateResizeBilinearOptions(_builder, node->align_corners(),
362 node->half_pixel_centers())
365 flatbuffers::Offset<void> visit(luci::CircleResizeNearestNeighbor *node)
367 return circle::CreateResizeNearestNeighborOptions(_builder, node->align_corners()).Union();
369 flatbuffers::Offset<void> visit(luci::CircleReverseSequence *node)
371 return circle::CreateReverseSequenceOptions(_builder, node->seq_axis(), node->batch_axis())
374 flatbuffers::Offset<void> visit(luci::CircleReverseV2 *)
376 return circle::CreateReverseV2Options(_builder).Union();
378 flatbuffers::Offset<void> visit(luci::CircleRound *) { return _no_option; }
379 flatbuffers::Offset<void> visit(luci::CircleRsqrt *) { return _no_option; }
380 flatbuffers::Offset<void> visit(luci::CircleScatterNd *)
382 return circle::CreateScatterNdOptions(_builder).Union();
384 flatbuffers::Offset<void> visit(luci::CircleSegmentSum *)
386 return circle::CreateSegmentSumOptions(_builder).Union();
388 flatbuffers::Offset<void> visit(luci::CircleSelect *)
390 return circle::CreateSelectOptions(_builder).Union();
392 flatbuffers::Offset<void> visit(luci::CircleSelectV2 *)
394 return circle::CreateSelectV2Options(_builder).Union();
396 flatbuffers::Offset<void> visit(luci::CircleShape *node)
398 return circle::CreateShapeOptions(_builder, luci::to_circle_tensortype(node->out_type()))
401 flatbuffers::Offset<void> visit(luci::CircleSin *) { return _no_option; }
402 flatbuffers::Offset<void> visit(luci::CircleSlice *)
404 return circle::CreateSliceOptions(_builder).Union();
406 flatbuffers::Offset<void> visit(luci::CircleSoftmax *node)
408 return circle::CreateSoftmaxOptions(_builder, node->beta()).Union();
410 flatbuffers::Offset<void> visit(luci::CircleSpaceToBatchND *)
412 return circle::CreateSpaceToBatchNDOptions(_builder).Union();
414 flatbuffers::Offset<void> visit(luci::CircleSpaceToDepth *node)
416 return circle::CreateSpaceToDepthOptions(_builder, node->block_size()).Union();
418 flatbuffers::Offset<void> visit(luci::CircleSparseToDense *node)
420 return circle::CreateSparseToDenseOptions(_builder, node->validate_indices()).Union();
422 flatbuffers::Offset<void> visit(luci::CircleSplit *node)
424 return circle::CreateSplitOptions(_builder, node->num_split()).Union();
426 flatbuffers::Offset<void> visit(luci::CircleSplitV *node)
428 return circle::CreateSplitVOptions(_builder, node->num_split()).Union();
430 flatbuffers::Offset<void> visit(luci::CircleSqrt *) { return _no_option; }
431 flatbuffers::Offset<void> visit(luci::CircleSquare *)
433 return circle::CreateSquareOptions(_builder).Union();
435 flatbuffers::Offset<void> visit(luci::CircleSquaredDifference *)
437 return circle::CreateSquaredDifferenceOptions(_builder).Union();
439 flatbuffers::Offset<void> visit(luci::CircleSqueeze *node)
441 auto squeeze_dims = _builder.CreateVector<int32_t>(node->squeeze_dims());
442 return circle::CreateSqueezeOptions(_builder, squeeze_dims).Union();
444 flatbuffers::Offset<void> visit(luci::CircleStridedSlice *node)
446 return circle::CreateStridedSliceOptions(_builder, node->begin_mask(), node->end_mask(),
447 node->ellipsis_mask(), node->new_axis_mask(),
448 node->shrink_axis_mask())
451 flatbuffers::Offset<void> visit(luci::CircleSub *node)
453 return circle::CreateSubOptions(_builder, to_circle_actfunc(node->fusedActivationFunction()))
456 flatbuffers::Offset<void> visit(luci::CircleSum *node)
458 return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
460 flatbuffers::Offset<void> visit(luci::CircleSVDF *node)
462 return circle::CreateSVDFOptions(_builder, node->svdf_rank(),
463 to_circle_actfunc(node->fusedActivationFunction()),
464 node->asymmetric_quantize_inputs())
467 flatbuffers::Offset<void> visit(luci::CircleTanh *) { return _no_option; }
468 flatbuffers::Offset<void> visit(luci::CircleTile *)
470 return circle::CreateTileOptions(_builder).Union();
472 flatbuffers::Offset<void> visit(luci::CircleTopKV2 *)
474 return circle::CreateTopKV2Options(_builder).Union();
476 flatbuffers::Offset<void> visit(luci::CircleTranspose *)
478 return circle::CreateTransposeOptions(_builder).Union();
480 flatbuffers::Offset<void> visit(luci::CircleTransposeConv *node)
482 return circle::CreateTransposeConvOptions(_builder, getOpPadding(node->padding()),
483 node->stride()->w(), node->stride()->h())
486 flatbuffers::Offset<void> visit(luci::CircleUnidirectionalSequenceLSTM *node)
488 return circle::CreateUnidirectionalSequenceLSTMOptions(
489 _builder, to_circle_actfunc(node->fusedActivationFunction()), node->cell_clip(),
490 node->proj_clip(), node->time_major(), node->asymmetric_quantize_inputs())
493 flatbuffers::Offset<void> visit(luci::CircleUnique *node)
495 return circle::CreateUniqueOptions(_builder, luci::to_circle_tensortype(node->idx_out_type()))
498 flatbuffers::Offset<void> visit(luci::CircleUnpack *node)
500 return circle::CreateUnpackOptions(_builder, node->num(), node->axis()).Union();
502 flatbuffers::Offset<void> visit(luci::CircleWhere *)
504 return circle::CreateWhereOptions(_builder).Union();
506 flatbuffers::Offset<void> visit(luci::CircleWhile *node)
508 return circle::CreateWhileOptions(_builder, node->cond_branch(), node->body_branch()).Union();
510 flatbuffers::Offset<void> visit(luci::CircleZerosLike *)
512 return circle::CreateZerosLikeOptions(_builder).Union();
515 flatbuffers::Offset<void> visit(luci::CircleBCQFullyConnected *node)
517 return circle::CreateBCQFullyConnectedOptions(
518 _builder, node->weights_hidden_size(),
519 to_circle_actfunc(node->fusedActivationFunction()))
522 flatbuffers::Offset<void> visit(luci::CircleBCQGather *node)
524 return circle::CreateBCQGatherOptions(_builder, node->input_hidden_size(), node->axis())
527 flatbuffers::Offset<void> visit(luci::CircleInstanceNorm *node)
529 return circle::CreateInstanceNormOptions(_builder, node->epsilon(),
530 to_circle_actfunc(node->fusedActivationFunction()))
535 flatbuffers::FlatBufferBuilder &_builder;
538 const flatbuffers::Offset<void> _no_option = 0;
543 #endif // __CIRCLE_BUILTIN_TYPES_EXTRACTOR_H__