Imported Upstream version 1.25.0
[platform/core/ml/nnfw.git] / compiler / luci / export / src / CircleBuiltinTypesExtractor.h
1 /*
2  * Copyright (c) 2021 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 #ifndef __CIRCLE_BUILTIN_TYPES_EXTRACTOR_H__
18 #define __CIRCLE_BUILTIN_TYPES_EXTRACTOR_H__
19
20 #include "CircleExporterUtils.h"
21
22 #include <luci/IR/CircleNode.h>
23 #include <luci/IR/CircleNodes.h>
24 #include <luci/IR/CircleNodeVisitor.h>
25
26 #include <flatbuffers/flexbuffers.h>
27
28 namespace luci
29 {
30
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>>
35 {
36 public:
37   BuiltinOptionsExtractor(flatbuffers::FlatBufferBuilder &builder) : _builder{builder}
38   {
39     // DO NOTHING
40   }
41
42 public:
43   flatbuffers::Offset<void> visit(luci::CircleAbs *)
44   {
45     return circle::CreateAbsOptions(_builder).Union();
46   }
47   flatbuffers::Offset<void> visit(luci::CircleAdd *node)
48   {
49     return circle::CreateAddOptions(_builder, to_circle_actfunc(node->fusedActivationFunction()))
50       .Union();
51   }
52   flatbuffers::Offset<void> visit(luci::CircleAddN *)
53   {
54     return circle::CreateAddNOptions(_builder).Union();
55   }
56   flatbuffers::Offset<void> visit(luci::CircleArgMax *node)
57   {
58     return circle::CreateArgMaxOptions(_builder, luci::to_circle_tensortype(node->output_type()))
59       .Union();
60   }
61   flatbuffers::Offset<void> visit(luci::CircleArgMin *node)
62   {
63     return circle::CreateArgMinOptions(_builder, luci::to_circle_tensortype(node->output_type()))
64       .Union();
65   }
66   flatbuffers::Offset<void> visit(luci::CircleAveragePool2D *node)
67   {
68     return circle::CreatePool2DOptions(_builder, getOpPadding(node->padding()), node->stride()->w(),
69                                        node->stride()->h(), node->filter()->w(),
70                                        node->filter()->h(),
71                                        to_circle_actfunc(node->fusedActivationFunction()))
72       .Union();
73   }
74   flatbuffers::Offset<void> visit(luci::CircleBatchMatMul *node)
75   {
76     return circle::CreateBatchMatMulOptions(_builder, node->adj_x(), node->adj_y()).Union();
77   }
78   flatbuffers::Offset<void> visit(luci::CircleBatchToSpaceND *)
79   {
80     return circle::CreateBatchToSpaceNDOptions(_builder).Union();
81   }
82   flatbuffers::Offset<void> visit(luci::CircleBidirectionalSequenceLSTM *node)
83   {
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())
88       .Union();
89   }
90   flatbuffers::Offset<void> visit(luci::CircleCast *node)
91   {
92     if (node->out_data_type() == loco::DataType::Unknown)
93       return _no_option;
94     else
95       return circle::CreateCastOptions(_builder, luci::to_circle_tensortype(node->in_data_type()),
96                                        luci::to_circle_tensortype(node->out_data_type()))
97         .Union();
98   }
99   flatbuffers::Offset<void> visit(luci::CircleCeil *) { return _no_option; }
100   flatbuffers::Offset<void> visit(luci::CircleConcatenation *node)
101   {
102     return circle::CreateConcatenationOptions(_builder, node->axis(),
103                                               to_circle_actfunc(node->fusedActivationFunction()))
104       .Union();
105   }
106   // CircleConst is not virtual but not builtinOperator
107   // flatbuffers::Offset<void> visit(luci::CircleConst *)
108   flatbuffers::Offset<void> visit(luci::CircleConv2D *node)
109   {
110     return circle::CreateConv2DOptions(_builder, getOpPadding(node->padding()), node->stride()->w(),
111                                        node->stride()->h(),
112                                        to_circle_actfunc(node->fusedActivationFunction()),
113                                        node->dilation()->w(), node->dilation()->h())
114       .Union();
115   }
116   flatbuffers::Offset<void> visit(luci::CircleCos *)
117   {
118     return circle::CreateCosOptions(_builder).Union();
119   }
120   flatbuffers::Offset<void> visit(luci::CircleCustom *) { return _no_option; }
121   flatbuffers::Offset<void> visit(luci::CircleDensify *)
122   {
123     return circle::CreateDensifyOptions(_builder).Union();
124   }
125   flatbuffers::Offset<void> visit(luci::CircleDepthToSpace *node)
126   {
127     return circle::CreateDepthToSpaceOptions(_builder, node->block_size()).Union();
128   }
129   flatbuffers::Offset<void> visit(luci::CircleDepthwiseConv2D *node)
130   {
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())
135       .Union();
136   }
137   flatbuffers::Offset<void> visit(luci::CircleDequantize *) { return _no_option; }
138   flatbuffers::Offset<void> visit(luci::CircleDiv *node)
139   {
140     return circle::CreateDivOptions(_builder, to_circle_actfunc(node->fusedActivationFunction()))
141       .Union();
142   }
143   flatbuffers::Offset<void> visit(luci::CircleElu *) { return _no_option; }
144   flatbuffers::Offset<void> visit(luci::CircleEqual *)
145   {
146     return circle::CreateEqualOptions(_builder).Union();
147   }
148   flatbuffers::Offset<void> visit(luci::CircleExp *)
149   {
150     return circle::CreateExpOptions(_builder).Union();
151   }
152   flatbuffers::Offset<void> visit(luci::CircleExpandDims *)
153   {
154     return circle::CreateExpandDimsOptions(_builder).Union();
155   }
156   flatbuffers::Offset<void> visit(luci::CircleFakeQuant *node)
157   {
158     return circle::CreateFakeQuantOptions(_builder, node->min(), node->max(), node->num_bits(),
159                                           node->narrow_range())
160       .Union();
161   }
162   flatbuffers::Offset<void> visit(luci::CircleFill *)
163   {
164     return circle::CreateFillOptions(_builder).Union();
165   }
166   flatbuffers::Offset<void> visit(luci::CircleFloor *) { return _no_option; }
167   flatbuffers::Offset<void> visit(luci::CircleFloorDiv *)
168   {
169     return circle::CreateFloorDivOptions(_builder).Union();
170   }
171   flatbuffers::Offset<void> visit(luci::CircleFloorMod *)
172   {
173     return circle::CreateFloorModOptions(_builder).Union();
174   }
175   flatbuffers::Offset<void> visit(luci::CircleFullyConnected *node)
176   {
177     return circle::CreateFullyConnectedOptions(
178              _builder, to_circle_actfunc(node->fusedActivationFunction()),
179              to_circle_weightsformat(node->weights_format()), node->keep_num_dims())
180       .Union();
181   }
182   flatbuffers::Offset<void> visit(luci::CircleGather *node)
183   {
184     return circle::CreateGatherOptions(_builder, node->axis()).Union();
185   }
186   flatbuffers::Offset<void> visit(luci::CircleGatherNd *)
187   {
188     return circle::CreateGatherNdOptions(_builder).Union();
189   }
190   flatbuffers::Offset<void> visit(luci::CircleGelu *node)
191   {
192     return circle::CreateGeluOptions(_builder, node->approximate()).Union();
193   }
194   flatbuffers::Offset<void> visit(luci::CircleGreater *)
195   {
196     return circle::CreateGreaterOptions(_builder).Union();
197   }
198   flatbuffers::Offset<void> visit(luci::CircleGreaterEqual *)
199   {
200     return circle::CreateGreaterEqualOptions(_builder).Union();
201   }
202   flatbuffers::Offset<void> visit(luci::CircleHardSwish *) { return _no_option; }
203   flatbuffers::Offset<void> visit(luci::CircleIf *node)
204   {
205     return circle::CreateIfOptions(_builder, node->then_branch(), node->else_branch()).Union();
206   }
207   flatbuffers::Offset<void> visit(luci::CircleL2Normalize *node)
208   {
209     return circle::CreateL2NormOptions(_builder, to_circle_actfunc(node->fusedActivationFunction()))
210       .Union();
211   }
212   flatbuffers::Offset<void> visit(luci::CircleL2Pool2D *node)
213   {
214     return circle::CreatePool2DOptions(_builder, getOpPadding(node->padding()), node->stride()->w(),
215                                        node->stride()->h(), node->filter()->w(),
216                                        node->filter()->h(),
217                                        to_circle_actfunc(node->fusedActivationFunction()))
218       .Union();
219   }
220   flatbuffers::Offset<void> visit(luci::CircleLeakyRelu *node)
221   {
222     return circle::CreateLeakyReluOptions(_builder, node->alpha()).Union();
223   }
224   flatbuffers::Offset<void> visit(luci::CircleLess *)
225   {
226     return circle::CreateLessOptions(_builder).Union();
227   }
228   flatbuffers::Offset<void> visit(luci::CircleLessEqual *)
229   {
230     return circle::CreateLessEqualOptions(_builder).Union();
231   }
232   flatbuffers::Offset<void> visit(luci::CircleLocalResponseNormalization *node)
233   {
234     return circle::CreateLocalResponseNormalizationOptions(_builder, node->radius(), node->bias(),
235                                                            node->alpha(), node->beta())
236       .Union();
237   }
238   flatbuffers::Offset<void> visit(luci::CircleLog *) { return _no_option; }
239   flatbuffers::Offset<void> visit(luci::CircleLogicalAnd *)
240   {
241     return circle::CreateLogicalAndOptions(_builder).Union();
242   }
243   flatbuffers::Offset<void> visit(luci::CircleLogicalNot *)
244   {
245     return circle::CreateLogicalNotOptions(_builder).Union();
246   }
247   flatbuffers::Offset<void> visit(luci::CircleLogicalOr *)
248   {
249     return circle::CreateLogicalOrOptions(_builder).Union();
250   }
251   flatbuffers::Offset<void> visit(luci::CircleLogistic *) { return _no_option; }
252   flatbuffers::Offset<void> visit(luci::CircleLogSoftmax *)
253   {
254     return circle::CreateLogSoftmaxOptions(_builder).Union();
255   }
256   flatbuffers::Offset<void> visit(luci::CircleMatrixDiag *)
257   {
258     return circle::CreateMatrixDiagOptions(_builder).Union();
259   }
260   flatbuffers::Offset<void> visit(luci::CircleMatrixSetDiag *)
261   {
262     return circle::CreateMatrixSetDiagOptions(_builder).Union();
263   }
264   flatbuffers::Offset<void> visit(luci::CircleMaximum *)
265   {
266     return circle::CreateMaximumMinimumOptions(_builder).Union();
267   }
268   flatbuffers::Offset<void> visit(luci::CircleMaxPool2D *node)
269   {
270     return circle::CreatePool2DOptions(_builder, getOpPadding(node->padding()), node->stride()->w(),
271                                        node->stride()->h(), node->filter()->w(),
272                                        node->filter()->h(),
273                                        to_circle_actfunc(node->fusedActivationFunction()))
274       .Union();
275   }
276   flatbuffers::Offset<void> visit(luci::CircleMean *node)
277   {
278     return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
279   }
280   flatbuffers::Offset<void> visit(luci::CircleMinimum *)
281   {
282     return circle::CreateMaximumMinimumOptions(_builder).Union();
283   }
284   flatbuffers::Offset<void> visit(luci::CircleMirrorPad *node)
285   {
286     return circle::CreateMirrorPadOptions(_builder, to_circle_mirrorpadmode(node->mode())).Union();
287   }
288   flatbuffers::Offset<void> visit(luci::CircleMul *node)
289   {
290     return circle::CreateMulOptions(_builder, to_circle_actfunc(node->fusedActivationFunction()))
291       .Union();
292   }
293   flatbuffers::Offset<void> visit(luci::CircleNeg *)
294   {
295     return circle::CreateNegOptions(_builder).Union();
296   }
297   flatbuffers::Offset<void> visit(luci::CircleNonMaxSuppressionV4 *)
298   {
299     return circle::CreateNonMaxSuppressionV4Options(_builder).Union();
300   }
301   flatbuffers::Offset<void> visit(luci::CircleNonMaxSuppressionV5 *)
302   {
303     return circle::CreateNonMaxSuppressionV5Options(_builder).Union();
304   }
305   flatbuffers::Offset<void> visit(luci::CircleNotEqual *)
306   {
307     return circle::CreateNotEqualOptions(_builder).Union();
308   }
309   flatbuffers::Offset<void> visit(luci::CircleOneHot *node)
310   {
311     return circle::CreateOneHotOptions(_builder, node->axis()).Union();
312   }
313   flatbuffers::Offset<void> visit(luci::CirclePack *node)
314   {
315     return circle::CreatePackOptions(_builder, node->values_count(), node->axis()).Union();
316   }
317   flatbuffers::Offset<void> visit(luci::CirclePad *)
318   {
319     return circle::CreatePadOptions(_builder).Union();
320   }
321   flatbuffers::Offset<void> visit(luci::CirclePadV2 *)
322   {
323     return circle::CreatePadV2Options(_builder).Union();
324   }
325   flatbuffers::Offset<void> visit(luci::CirclePow *)
326   {
327     return circle::CreatePowOptions(_builder).Union();
328   }
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 *)
332   {
333     return circle::CreateRangeOptions(_builder).Union();
334   }
335   flatbuffers::Offset<void> visit(luci::CircleRank *)
336   {
337     return circle::CreateRankOptions(_builder).Union();
338   }
339   flatbuffers::Offset<void> visit(luci::CircleReduceAny *node)
340   {
341     return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
342   }
343   flatbuffers::Offset<void> visit(luci::CircleReduceMax *node)
344   {
345     return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
346   }
347   flatbuffers::Offset<void> visit(luci::CircleReduceMin *node)
348   {
349     return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
350   }
351   flatbuffers::Offset<void> visit(luci::CircleReduceProd *node)
352   {
353     return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
354   }
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)
359   {
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();
363   }
364   flatbuffers::Offset<void> visit(luci::CircleResizeBilinear *node)
365   {
366     return circle::CreateResizeBilinearOptions(_builder, node->align_corners(),
367                                                node->half_pixel_centers())
368       .Union();
369   }
370   flatbuffers::Offset<void> visit(luci::CircleResizeNearestNeighbor *node)
371   {
372     return circle::CreateResizeNearestNeighborOptions(_builder, node->align_corners()).Union();
373   }
374   flatbuffers::Offset<void> visit(luci::CircleReverseSequence *node)
375   {
376     return circle::CreateReverseSequenceOptions(_builder, node->seq_axis(), node->batch_axis())
377       .Union();
378   }
379   flatbuffers::Offset<void> visit(luci::CircleReverseV2 *)
380   {
381     return circle::CreateReverseV2Options(_builder).Union();
382   }
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 *)
386   {
387     return circle::CreateScatterNdOptions(_builder).Union();
388   }
389   flatbuffers::Offset<void> visit(luci::CircleSegmentSum *)
390   {
391     return circle::CreateSegmentSumOptions(_builder).Union();
392   }
393   flatbuffers::Offset<void> visit(luci::CircleSelect *)
394   {
395     return circle::CreateSelectOptions(_builder).Union();
396   }
397   flatbuffers::Offset<void> visit(luci::CircleSelectV2 *)
398   {
399     return circle::CreateSelectV2Options(_builder).Union();
400   }
401   flatbuffers::Offset<void> visit(luci::CircleShape *node)
402   {
403     return circle::CreateShapeOptions(_builder, luci::to_circle_tensortype(node->out_type()))
404       .Union();
405   }
406   flatbuffers::Offset<void> visit(luci::CircleSin *) { return _no_option; }
407   flatbuffers::Offset<void> visit(luci::CircleSlice *)
408   {
409     return circle::CreateSliceOptions(_builder).Union();
410   }
411   flatbuffers::Offset<void> visit(luci::CircleSoftmax *node)
412   {
413     return circle::CreateSoftmaxOptions(_builder, node->beta()).Union();
414   }
415   flatbuffers::Offset<void> visit(luci::CircleSpaceToBatchND *)
416   {
417     return circle::CreateSpaceToBatchNDOptions(_builder).Union();
418   }
419   flatbuffers::Offset<void> visit(luci::CircleSpaceToDepth *node)
420   {
421     return circle::CreateSpaceToDepthOptions(_builder, node->block_size()).Union();
422   }
423   flatbuffers::Offset<void> visit(luci::CircleSparseToDense *node)
424   {
425     return circle::CreateSparseToDenseOptions(_builder, node->validate_indices()).Union();
426   }
427   flatbuffers::Offset<void> visit(luci::CircleSplit *node)
428   {
429     return circle::CreateSplitOptions(_builder, node->num_split()).Union();
430   }
431   flatbuffers::Offset<void> visit(luci::CircleSplitV *node)
432   {
433     return circle::CreateSplitVOptions(_builder, node->num_split()).Union();
434   }
435   flatbuffers::Offset<void> visit(luci::CircleSqrt *) { return _no_option; }
436   flatbuffers::Offset<void> visit(luci::CircleSquare *)
437   {
438     return circle::CreateSquareOptions(_builder).Union();
439   }
440   flatbuffers::Offset<void> visit(luci::CircleSquaredDifference *)
441   {
442     return circle::CreateSquaredDifferenceOptions(_builder).Union();
443   }
444   flatbuffers::Offset<void> visit(luci::CircleSqueeze *node)
445   {
446     auto squeeze_dims = _builder.CreateVector<int32_t>(node->squeeze_dims());
447     return circle::CreateSqueezeOptions(_builder, squeeze_dims).Union();
448   }
449   flatbuffers::Offset<void> visit(luci::CircleStridedSlice *node)
450   {
451     return circle::CreateStridedSliceOptions(_builder, node->begin_mask(), node->end_mask(),
452                                              node->ellipsis_mask(), node->new_axis_mask(),
453                                              node->shrink_axis_mask())
454       .Union();
455   }
456   flatbuffers::Offset<void> visit(luci::CircleSub *node)
457   {
458     return circle::CreateSubOptions(_builder, to_circle_actfunc(node->fusedActivationFunction()))
459       .Union();
460   }
461   flatbuffers::Offset<void> visit(luci::CircleSum *node)
462   {
463     return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
464   }
465   flatbuffers::Offset<void> visit(luci::CircleSVDF *node)
466   {
467     return circle::CreateSVDFOptions(_builder, node->svdf_rank(),
468                                      to_circle_actfunc(node->fusedActivationFunction()),
469                                      node->asymmetric_quantize_inputs())
470       .Union();
471   }
472   flatbuffers::Offset<void> visit(luci::CircleTanh *) { return _no_option; }
473   flatbuffers::Offset<void> visit(luci::CircleTile *)
474   {
475     return circle::CreateTileOptions(_builder).Union();
476   }
477   flatbuffers::Offset<void> visit(luci::CircleTopKV2 *)
478   {
479     return circle::CreateTopKV2Options(_builder).Union();
480   }
481   flatbuffers::Offset<void> visit(luci::CircleTranspose *)
482   {
483     return circle::CreateTransposeOptions(_builder).Union();
484   }
485   flatbuffers::Offset<void> visit(luci::CircleTransposeConv *node)
486   {
487     return circle::CreateTransposeConvOptions(_builder, getOpPadding(node->padding()),
488                                               node->stride()->w(), node->stride()->h(),
489                                               to_circle_actfunc(node->fusedActivationFunction()))
490       .Union();
491   }
492   flatbuffers::Offset<void> visit(luci::CircleUnidirectionalSequenceLSTM *node)
493   {
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())
497       .Union();
498   }
499   flatbuffers::Offset<void> visit(luci::CircleUnique *node)
500   {
501     return circle::CreateUniqueOptions(_builder, luci::to_circle_tensortype(node->idx_out_type()))
502       .Union();
503   }
504   flatbuffers::Offset<void> visit(luci::CircleUnpack *node)
505   {
506     return circle::CreateUnpackOptions(_builder, node->num(), node->axis()).Union();
507   }
508   flatbuffers::Offset<void> visit(luci::CircleWhere *)
509   {
510     return circle::CreateWhereOptions(_builder).Union();
511   }
512   flatbuffers::Offset<void> visit(luci::CircleWhile *node)
513   {
514     return circle::CreateWhileOptions(_builder, node->cond_branch(), node->body_branch()).Union();
515   }
516   flatbuffers::Offset<void> visit(luci::CircleZerosLike *)
517   {
518     return circle::CreateZerosLikeOptions(_builder).Union();
519   }
520   // Circle only
521   flatbuffers::Offset<void> visit(luci::CircleBCQFullyConnected *node)
522   {
523     return circle::CreateBCQFullyConnectedOptions(
524              _builder, node->weights_hidden_size(),
525              to_circle_actfunc(node->fusedActivationFunction()))
526       .Union();
527   }
528   flatbuffers::Offset<void> visit(luci::CircleBCQGather *node)
529   {
530     return circle::CreateBCQGatherOptions(_builder, node->input_hidden_size(), node->axis())
531       .Union();
532   }
533   flatbuffers::Offset<void> visit(luci::CircleInstanceNorm *node)
534   {
535     return circle::CreateInstanceNormOptions(_builder, node->epsilon(),
536                                              to_circle_actfunc(node->fusedActivationFunction()))
537       .Union();
538   }
539
540 protected:
541   flatbuffers::FlatBufferBuilder &_builder;
542
543 private:
544   const flatbuffers::Offset<void> _no_option = 0;
545 };
546
547 } // namespace luci
548
549 #endif // __CIRCLE_BUILTIN_TYPES_EXTRACTOR_H__