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::CircleGelu *node)
192 return circle::CreateGeluOptions(_builder, node->approximate()).Union();
194 flatbuffers::Offset<void> visit(luci::CircleGreater *)
196 return circle::CreateGreaterOptions(_builder).Union();
198 flatbuffers::Offset<void> visit(luci::CircleGreaterEqual *)
200 return circle::CreateGreaterEqualOptions(_builder).Union();
202 flatbuffers::Offset<void> visit(luci::CircleHardSwish *) { return _no_option; }
203 flatbuffers::Offset<void> visit(luci::CircleIf *node)
205 return circle::CreateIfOptions(_builder, node->then_branch(), node->else_branch()).Union();
207 flatbuffers::Offset<void> visit(luci::CircleL2Normalize *node)
209 return circle::CreateL2NormOptions(_builder, to_circle_actfunc(node->fusedActivationFunction()))
212 flatbuffers::Offset<void> visit(luci::CircleL2Pool2D *node)
214 return circle::CreatePool2DOptions(_builder, getOpPadding(node->padding()), node->stride()->w(),
215 node->stride()->h(), node->filter()->w(),
217 to_circle_actfunc(node->fusedActivationFunction()))
220 flatbuffers::Offset<void> visit(luci::CircleLeakyRelu *node)
222 return circle::CreateLeakyReluOptions(_builder, node->alpha()).Union();
224 flatbuffers::Offset<void> visit(luci::CircleLess *)
226 return circle::CreateLessOptions(_builder).Union();
228 flatbuffers::Offset<void> visit(luci::CircleLessEqual *)
230 return circle::CreateLessEqualOptions(_builder).Union();
232 flatbuffers::Offset<void> visit(luci::CircleLocalResponseNormalization *node)
234 return circle::CreateLocalResponseNormalizationOptions(_builder, node->radius(), node->bias(),
235 node->alpha(), node->beta())
238 flatbuffers::Offset<void> visit(luci::CircleLog *) { return _no_option; }
239 flatbuffers::Offset<void> visit(luci::CircleLogicalAnd *)
241 return circle::CreateLogicalAndOptions(_builder).Union();
243 flatbuffers::Offset<void> visit(luci::CircleLogicalNot *)
245 return circle::CreateLogicalNotOptions(_builder).Union();
247 flatbuffers::Offset<void> visit(luci::CircleLogicalOr *)
249 return circle::CreateLogicalOrOptions(_builder).Union();
251 flatbuffers::Offset<void> visit(luci::CircleLogistic *) { return _no_option; }
252 flatbuffers::Offset<void> visit(luci::CircleLogSoftmax *)
254 return circle::CreateLogSoftmaxOptions(_builder).Union();
256 flatbuffers::Offset<void> visit(luci::CircleMatrixDiag *)
258 return circle::CreateMatrixDiagOptions(_builder).Union();
260 flatbuffers::Offset<void> visit(luci::CircleMatrixSetDiag *)
262 return circle::CreateMatrixSetDiagOptions(_builder).Union();
264 flatbuffers::Offset<void> visit(luci::CircleMaximum *)
266 return circle::CreateMaximumMinimumOptions(_builder).Union();
268 flatbuffers::Offset<void> visit(luci::CircleMaxPool2D *node)
270 return circle::CreatePool2DOptions(_builder, getOpPadding(node->padding()), node->stride()->w(),
271 node->stride()->h(), node->filter()->w(),
273 to_circle_actfunc(node->fusedActivationFunction()))
276 flatbuffers::Offset<void> visit(luci::CircleMean *node)
278 return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
280 flatbuffers::Offset<void> visit(luci::CircleMinimum *)
282 return circle::CreateMaximumMinimumOptions(_builder).Union();
284 flatbuffers::Offset<void> visit(luci::CircleMirrorPad *node)
286 return circle::CreateMirrorPadOptions(_builder, to_circle_mirrorpadmode(node->mode())).Union();
288 flatbuffers::Offset<void> visit(luci::CircleMul *node)
290 return circle::CreateMulOptions(_builder, to_circle_actfunc(node->fusedActivationFunction()))
293 flatbuffers::Offset<void> visit(luci::CircleNeg *)
295 return circle::CreateNegOptions(_builder).Union();
297 flatbuffers::Offset<void> visit(luci::CircleNonMaxSuppressionV4 *)
299 return circle::CreateNonMaxSuppressionV4Options(_builder).Union();
301 flatbuffers::Offset<void> visit(luci::CircleNonMaxSuppressionV5 *)
303 return circle::CreateNonMaxSuppressionV5Options(_builder).Union();
305 flatbuffers::Offset<void> visit(luci::CircleNotEqual *)
307 return circle::CreateNotEqualOptions(_builder).Union();
309 flatbuffers::Offset<void> visit(luci::CircleOneHot *node)
311 return circle::CreateOneHotOptions(_builder, node->axis()).Union();
313 flatbuffers::Offset<void> visit(luci::CirclePack *node)
315 return circle::CreatePackOptions(_builder, node->values_count(), node->axis()).Union();
317 flatbuffers::Offset<void> visit(luci::CirclePad *)
319 return circle::CreatePadOptions(_builder).Union();
321 flatbuffers::Offset<void> visit(luci::CirclePadV2 *)
323 return circle::CreatePadV2Options(_builder).Union();
325 flatbuffers::Offset<void> visit(luci::CirclePow *)
327 return circle::CreatePowOptions(_builder).Union();
329 flatbuffers::Offset<void> visit(luci::CirclePRelu *) { return _no_option; }
330 flatbuffers::Offset<void> visit(luci::CircleQuantize *) { return _no_option; }
331 flatbuffers::Offset<void> visit(luci::CircleRange *)
333 return circle::CreateRangeOptions(_builder).Union();
335 flatbuffers::Offset<void> visit(luci::CircleRank *)
337 return circle::CreateRankOptions(_builder).Union();
339 flatbuffers::Offset<void> visit(luci::CircleReduceAny *node)
341 return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
343 flatbuffers::Offset<void> visit(luci::CircleReduceMax *node)
345 return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
347 flatbuffers::Offset<void> visit(luci::CircleReduceMin *node)
349 return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
351 flatbuffers::Offset<void> visit(luci::CircleReduceProd *node)
353 return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
355 flatbuffers::Offset<void> visit(luci::CircleRelu *) { return _no_option; }
356 flatbuffers::Offset<void> visit(luci::CircleRelu6 *) { return _no_option; }
357 flatbuffers::Offset<void> visit(luci::CircleReluN1To1 *) { return _no_option; }
358 flatbuffers::Offset<void> visit(luci::CircleReshape *node)
360 auto new_shape = _builder.CreateVector<int32_t>(
361 node->newShape()->rank(), [node](size_t i) { return node->newShape()->dim(i); });
362 return circle::CreateReshapeOptions(_builder, new_shape).Union();
364 flatbuffers::Offset<void> visit(luci::CircleResizeBilinear *node)
366 return circle::CreateResizeBilinearOptions(_builder, node->align_corners(),
367 node->half_pixel_centers())
370 flatbuffers::Offset<void> visit(luci::CircleResizeNearestNeighbor *node)
372 return circle::CreateResizeNearestNeighborOptions(_builder, node->align_corners()).Union();
374 flatbuffers::Offset<void> visit(luci::CircleReverseSequence *node)
376 return circle::CreateReverseSequenceOptions(_builder, node->seq_axis(), node->batch_axis())
379 flatbuffers::Offset<void> visit(luci::CircleReverseV2 *)
381 return circle::CreateReverseV2Options(_builder).Union();
383 flatbuffers::Offset<void> visit(luci::CircleRound *) { return _no_option; }
384 flatbuffers::Offset<void> visit(luci::CircleRsqrt *) { return _no_option; }
385 flatbuffers::Offset<void> visit(luci::CircleScatterNd *)
387 return circle::CreateScatterNdOptions(_builder).Union();
389 flatbuffers::Offset<void> visit(luci::CircleSegmentSum *)
391 return circle::CreateSegmentSumOptions(_builder).Union();
393 flatbuffers::Offset<void> visit(luci::CircleSelect *)
395 return circle::CreateSelectOptions(_builder).Union();
397 flatbuffers::Offset<void> visit(luci::CircleSelectV2 *)
399 return circle::CreateSelectV2Options(_builder).Union();
401 flatbuffers::Offset<void> visit(luci::CircleShape *node)
403 return circle::CreateShapeOptions(_builder, luci::to_circle_tensortype(node->out_type()))
406 flatbuffers::Offset<void> visit(luci::CircleSin *) { return _no_option; }
407 flatbuffers::Offset<void> visit(luci::CircleSlice *)
409 return circle::CreateSliceOptions(_builder).Union();
411 flatbuffers::Offset<void> visit(luci::CircleSoftmax *node)
413 return circle::CreateSoftmaxOptions(_builder, node->beta()).Union();
415 flatbuffers::Offset<void> visit(luci::CircleSpaceToBatchND *)
417 return circle::CreateSpaceToBatchNDOptions(_builder).Union();
419 flatbuffers::Offset<void> visit(luci::CircleSpaceToDepth *node)
421 return circle::CreateSpaceToDepthOptions(_builder, node->block_size()).Union();
423 flatbuffers::Offset<void> visit(luci::CircleSparseToDense *node)
425 return circle::CreateSparseToDenseOptions(_builder, node->validate_indices()).Union();
427 flatbuffers::Offset<void> visit(luci::CircleSplit *node)
429 return circle::CreateSplitOptions(_builder, node->num_split()).Union();
431 flatbuffers::Offset<void> visit(luci::CircleSplitV *node)
433 return circle::CreateSplitVOptions(_builder, node->num_split()).Union();
435 flatbuffers::Offset<void> visit(luci::CircleSqrt *) { return _no_option; }
436 flatbuffers::Offset<void> visit(luci::CircleSquare *)
438 return circle::CreateSquareOptions(_builder).Union();
440 flatbuffers::Offset<void> visit(luci::CircleSquaredDifference *)
442 return circle::CreateSquaredDifferenceOptions(_builder).Union();
444 flatbuffers::Offset<void> visit(luci::CircleSqueeze *node)
446 auto squeeze_dims = _builder.CreateVector<int32_t>(node->squeeze_dims());
447 return circle::CreateSqueezeOptions(_builder, squeeze_dims).Union();
449 flatbuffers::Offset<void> visit(luci::CircleStridedSlice *node)
451 return circle::CreateStridedSliceOptions(_builder, node->begin_mask(), node->end_mask(),
452 node->ellipsis_mask(), node->new_axis_mask(),
453 node->shrink_axis_mask())
456 flatbuffers::Offset<void> visit(luci::CircleSub *node)
458 return circle::CreateSubOptions(_builder, to_circle_actfunc(node->fusedActivationFunction()))
461 flatbuffers::Offset<void> visit(luci::CircleSum *node)
463 return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
465 flatbuffers::Offset<void> visit(luci::CircleSVDF *node)
467 return circle::CreateSVDFOptions(_builder, node->svdf_rank(),
468 to_circle_actfunc(node->fusedActivationFunction()),
469 node->asymmetric_quantize_inputs())
472 flatbuffers::Offset<void> visit(luci::CircleTanh *) { return _no_option; }
473 flatbuffers::Offset<void> visit(luci::CircleTile *)
475 return circle::CreateTileOptions(_builder).Union();
477 flatbuffers::Offset<void> visit(luci::CircleTopKV2 *)
479 return circle::CreateTopKV2Options(_builder).Union();
481 flatbuffers::Offset<void> visit(luci::CircleTranspose *)
483 return circle::CreateTransposeOptions(_builder).Union();
485 flatbuffers::Offset<void> visit(luci::CircleTransposeConv *node)
487 return circle::CreateTransposeConvOptions(_builder, getOpPadding(node->padding()),
488 node->stride()->w(), node->stride()->h(),
489 to_circle_actfunc(node->fusedActivationFunction()))
492 flatbuffers::Offset<void> visit(luci::CircleUnidirectionalSequenceLSTM *node)
494 return circle::CreateUnidirectionalSequenceLSTMOptions(
495 _builder, to_circle_actfunc(node->fusedActivationFunction()), node->cell_clip(),
496 node->proj_clip(), node->time_major(), node->asymmetric_quantize_inputs())
499 flatbuffers::Offset<void> visit(luci::CircleUnique *node)
501 return circle::CreateUniqueOptions(_builder, luci::to_circle_tensortype(node->idx_out_type()))
504 flatbuffers::Offset<void> visit(luci::CircleUnpack *node)
506 return circle::CreateUnpackOptions(_builder, node->num(), node->axis()).Union();
508 flatbuffers::Offset<void> visit(luci::CircleWhere *)
510 return circle::CreateWhereOptions(_builder).Union();
512 flatbuffers::Offset<void> visit(luci::CircleWhile *node)
514 return circle::CreateWhileOptions(_builder, node->cond_branch(), node->body_branch()).Union();
516 flatbuffers::Offset<void> visit(luci::CircleZerosLike *)
518 return circle::CreateZerosLikeOptions(_builder).Union();
521 flatbuffers::Offset<void> visit(luci::CircleBCQFullyConnected *node)
523 return circle::CreateBCQFullyConnectedOptions(
524 _builder, node->weights_hidden_size(),
525 to_circle_actfunc(node->fusedActivationFunction()))
528 flatbuffers::Offset<void> visit(luci::CircleBCQGather *node)
530 return circle::CreateBCQGatherOptions(_builder, node->input_hidden_size(), node->axis())
533 flatbuffers::Offset<void> visit(luci::CircleInstanceNorm *node)
535 return circle::CreateInstanceNormOptions(_builder, node->epsilon(),
536 to_circle_actfunc(node->fusedActivationFunction()))
541 flatbuffers::FlatBufferBuilder &_builder;
544 const flatbuffers::Offset<void> _no_option = 0;
549 #endif // __CIRCLE_BUILTIN_TYPES_EXTRACTOR_H__