7516197c0eec72ce5deeadab13c2c8b76044ceeb
[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::CircleGreater *)
191   {
192     return circle::CreateGreaterOptions(_builder).Union();
193   }
194   flatbuffers::Offset<void> visit(luci::CircleGreaterEqual *)
195   {
196     return circle::CreateGreaterEqualOptions(_builder).Union();
197   }
198   flatbuffers::Offset<void> visit(luci::CircleIf *node)
199   {
200     return circle::CreateIfOptions(_builder, node->then_branch(), node->else_branch()).Union();
201   }
202   flatbuffers::Offset<void> visit(luci::CircleL2Normalize *node)
203   {
204     return circle::CreateL2NormOptions(_builder, to_circle_actfunc(node->fusedActivationFunction()))
205       .Union();
206   }
207   flatbuffers::Offset<void> visit(luci::CircleL2Pool2D *node)
208   {
209     return circle::CreatePool2DOptions(_builder, getOpPadding(node->padding()), node->stride()->w(),
210                                        node->stride()->h(), node->filter()->w(),
211                                        node->filter()->h(),
212                                        to_circle_actfunc(node->fusedActivationFunction()))
213       .Union();
214   }
215   flatbuffers::Offset<void> visit(luci::CircleLeakyRelu *node)
216   {
217     return circle::CreateLeakyReluOptions(_builder, node->alpha()).Union();
218   }
219   flatbuffers::Offset<void> visit(luci::CircleLess *)
220   {
221     return circle::CreateLessOptions(_builder).Union();
222   }
223   flatbuffers::Offset<void> visit(luci::CircleLessEqual *)
224   {
225     return circle::CreateLessEqualOptions(_builder).Union();
226   }
227   flatbuffers::Offset<void> visit(luci::CircleLocalResponseNormalization *node)
228   {
229     return circle::CreateLocalResponseNormalizationOptions(_builder, node->radius(), node->bias(),
230                                                            node->alpha(), node->beta())
231       .Union();
232   }
233   flatbuffers::Offset<void> visit(luci::CircleLog *) { return _no_option; }
234   flatbuffers::Offset<void> visit(luci::CircleLogicalAnd *)
235   {
236     return circle::CreateLogicalAndOptions(_builder).Union();
237   }
238   flatbuffers::Offset<void> visit(luci::CircleLogicalNot *)
239   {
240     return circle::CreateLogicalNotOptions(_builder).Union();
241   }
242   flatbuffers::Offset<void> visit(luci::CircleLogicalOr *)
243   {
244     return circle::CreateLogicalOrOptions(_builder).Union();
245   }
246   flatbuffers::Offset<void> visit(luci::CircleLogistic *) { return _no_option; }
247   flatbuffers::Offset<void> visit(luci::CircleLogSoftmax *)
248   {
249     return circle::CreateLogSoftmaxOptions(_builder).Union();
250   }
251   flatbuffers::Offset<void> visit(luci::CircleMatrixDiag *)
252   {
253     return circle::CreateMatrixDiagOptions(_builder).Union();
254   }
255   flatbuffers::Offset<void> visit(luci::CircleMatrixSetDiag *)
256   {
257     return circle::CreateMatrixSetDiagOptions(_builder).Union();
258   }
259   flatbuffers::Offset<void> visit(luci::CircleMaximum *)
260   {
261     return circle::CreateMaximumMinimumOptions(_builder).Union();
262   }
263   flatbuffers::Offset<void> visit(luci::CircleMaxPool2D *node)
264   {
265     return circle::CreatePool2DOptions(_builder, getOpPadding(node->padding()), node->stride()->w(),
266                                        node->stride()->h(), node->filter()->w(),
267                                        node->filter()->h(),
268                                        to_circle_actfunc(node->fusedActivationFunction()))
269       .Union();
270   }
271   flatbuffers::Offset<void> visit(luci::CircleMean *node)
272   {
273     return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
274   }
275   flatbuffers::Offset<void> visit(luci::CircleMinimum *)
276   {
277     return circle::CreateMaximumMinimumOptions(_builder).Union();
278   }
279   flatbuffers::Offset<void> visit(luci::CircleMirrorPad *node)
280   {
281     return circle::CreateMirrorPadOptions(_builder, to_circle_mirrorpadmode(node->mode())).Union();
282   }
283   flatbuffers::Offset<void> visit(luci::CircleMul *node)
284   {
285     return circle::CreateMulOptions(_builder, to_circle_actfunc(node->fusedActivationFunction()))
286       .Union();
287   }
288   flatbuffers::Offset<void> visit(luci::CircleNeg *)
289   {
290     return circle::CreateNegOptions(_builder).Union();
291   }
292   flatbuffers::Offset<void> visit(luci::CircleNonMaxSuppressionV4 *)
293   {
294     return circle::CreateNonMaxSuppressionV4Options(_builder).Union();
295   }
296   flatbuffers::Offset<void> visit(luci::CircleNonMaxSuppressionV5 *)
297   {
298     return circle::CreateNonMaxSuppressionV5Options(_builder).Union();
299   }
300   flatbuffers::Offset<void> visit(luci::CircleNotEqual *)
301   {
302     return circle::CreateNotEqualOptions(_builder).Union();
303   }
304   flatbuffers::Offset<void> visit(luci::CircleOneHot *node)
305   {
306     return circle::CreateOneHotOptions(_builder, node->axis()).Union();
307   }
308   flatbuffers::Offset<void> visit(luci::CirclePack *node)
309   {
310     return circle::CreatePackOptions(_builder, node->values_count(), node->axis()).Union();
311   }
312   flatbuffers::Offset<void> visit(luci::CirclePad *)
313   {
314     return circle::CreatePadOptions(_builder).Union();
315   }
316   flatbuffers::Offset<void> visit(luci::CirclePadV2 *)
317   {
318     return circle::CreatePadV2Options(_builder).Union();
319   }
320   flatbuffers::Offset<void> visit(luci::CirclePow *)
321   {
322     return circle::CreatePowOptions(_builder).Union();
323   }
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 *)
327   {
328     return circle::CreateRangeOptions(_builder).Union();
329   }
330   flatbuffers::Offset<void> visit(luci::CircleRank *)
331   {
332     return circle::CreateRankOptions(_builder).Union();
333   }
334   flatbuffers::Offset<void> visit(luci::CircleReduceAny *node)
335   {
336     return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
337   }
338   flatbuffers::Offset<void> visit(luci::CircleReduceMax *node)
339   {
340     return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
341   }
342   flatbuffers::Offset<void> visit(luci::CircleReduceMin *node)
343   {
344     return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
345   }
346   flatbuffers::Offset<void> visit(luci::CircleReduceProd *node)
347   {
348     return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
349   }
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)
354   {
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();
358   }
359   flatbuffers::Offset<void> visit(luci::CircleResizeBilinear *node)
360   {
361     return circle::CreateResizeBilinearOptions(_builder, node->align_corners(),
362                                                node->half_pixel_centers())
363       .Union();
364   }
365   flatbuffers::Offset<void> visit(luci::CircleResizeNearestNeighbor *node)
366   {
367     return circle::CreateResizeNearestNeighborOptions(_builder, node->align_corners()).Union();
368   }
369   flatbuffers::Offset<void> visit(luci::CircleReverseSequence *node)
370   {
371     return circle::CreateReverseSequenceOptions(_builder, node->seq_axis(), node->batch_axis())
372       .Union();
373   }
374   flatbuffers::Offset<void> visit(luci::CircleReverseV2 *)
375   {
376     return circle::CreateReverseV2Options(_builder).Union();
377   }
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 *)
381   {
382     return circle::CreateScatterNdOptions(_builder).Union();
383   }
384   flatbuffers::Offset<void> visit(luci::CircleSegmentSum *)
385   {
386     return circle::CreateSegmentSumOptions(_builder).Union();
387   }
388   flatbuffers::Offset<void> visit(luci::CircleSelect *)
389   {
390     return circle::CreateSelectOptions(_builder).Union();
391   }
392   flatbuffers::Offset<void> visit(luci::CircleSelectV2 *)
393   {
394     return circle::CreateSelectV2Options(_builder).Union();
395   }
396   flatbuffers::Offset<void> visit(luci::CircleShape *node)
397   {
398     return circle::CreateShapeOptions(_builder, luci::to_circle_tensortype(node->out_type()))
399       .Union();
400   }
401   flatbuffers::Offset<void> visit(luci::CircleSin *) { return _no_option; }
402   flatbuffers::Offset<void> visit(luci::CircleSlice *)
403   {
404     return circle::CreateSliceOptions(_builder).Union();
405   }
406   flatbuffers::Offset<void> visit(luci::CircleSoftmax *node)
407   {
408     return circle::CreateSoftmaxOptions(_builder, node->beta()).Union();
409   }
410   flatbuffers::Offset<void> visit(luci::CircleSpaceToBatchND *)
411   {
412     return circle::CreateSpaceToBatchNDOptions(_builder).Union();
413   }
414   flatbuffers::Offset<void> visit(luci::CircleSpaceToDepth *node)
415   {
416     return circle::CreateSpaceToDepthOptions(_builder, node->block_size()).Union();
417   }
418   flatbuffers::Offset<void> visit(luci::CircleSparseToDense *node)
419   {
420     return circle::CreateSparseToDenseOptions(_builder, node->validate_indices()).Union();
421   }
422   flatbuffers::Offset<void> visit(luci::CircleSplit *node)
423   {
424     return circle::CreateSplitOptions(_builder, node->num_split()).Union();
425   }
426   flatbuffers::Offset<void> visit(luci::CircleSplitV *node)
427   {
428     return circle::CreateSplitVOptions(_builder, node->num_split()).Union();
429   }
430   flatbuffers::Offset<void> visit(luci::CircleSqrt *) { return _no_option; }
431   flatbuffers::Offset<void> visit(luci::CircleSquare *)
432   {
433     return circle::CreateSquareOptions(_builder).Union();
434   }
435   flatbuffers::Offset<void> visit(luci::CircleSquaredDifference *)
436   {
437     return circle::CreateSquaredDifferenceOptions(_builder).Union();
438   }
439   flatbuffers::Offset<void> visit(luci::CircleSqueeze *node)
440   {
441     auto squeeze_dims = _builder.CreateVector<int32_t>(node->squeeze_dims());
442     return circle::CreateSqueezeOptions(_builder, squeeze_dims).Union();
443   }
444   flatbuffers::Offset<void> visit(luci::CircleStridedSlice *node)
445   {
446     return circle::CreateStridedSliceOptions(_builder, node->begin_mask(), node->end_mask(),
447                                              node->ellipsis_mask(), node->new_axis_mask(),
448                                              node->shrink_axis_mask())
449       .Union();
450   }
451   flatbuffers::Offset<void> visit(luci::CircleSub *node)
452   {
453     return circle::CreateSubOptions(_builder, to_circle_actfunc(node->fusedActivationFunction()))
454       .Union();
455   }
456   flatbuffers::Offset<void> visit(luci::CircleSum *node)
457   {
458     return circle::CreateReducerOptions(_builder, node->keep_dims()).Union();
459   }
460   flatbuffers::Offset<void> visit(luci::CircleSVDF *node)
461   {
462     return circle::CreateSVDFOptions(_builder, node->svdf_rank(),
463                                      to_circle_actfunc(node->fusedActivationFunction()),
464                                      node->asymmetric_quantize_inputs())
465       .Union();
466   }
467   flatbuffers::Offset<void> visit(luci::CircleTanh *) { return _no_option; }
468   flatbuffers::Offset<void> visit(luci::CircleTile *)
469   {
470     return circle::CreateTileOptions(_builder).Union();
471   }
472   flatbuffers::Offset<void> visit(luci::CircleTopKV2 *)
473   {
474     return circle::CreateTopKV2Options(_builder).Union();
475   }
476   flatbuffers::Offset<void> visit(luci::CircleTranspose *)
477   {
478     return circle::CreateTransposeOptions(_builder).Union();
479   }
480   flatbuffers::Offset<void> visit(luci::CircleTransposeConv *node)
481   {
482     return circle::CreateTransposeConvOptions(_builder, getOpPadding(node->padding()),
483                                               node->stride()->w(), node->stride()->h())
484       .Union();
485   }
486   flatbuffers::Offset<void> visit(luci::CircleUnidirectionalSequenceLSTM *node)
487   {
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())
491       .Union();
492   }
493   flatbuffers::Offset<void> visit(luci::CircleUnique *node)
494   {
495     return circle::CreateUniqueOptions(_builder, luci::to_circle_tensortype(node->idx_out_type()))
496       .Union();
497   }
498   flatbuffers::Offset<void> visit(luci::CircleUnpack *node)
499   {
500     return circle::CreateUnpackOptions(_builder, node->num(), node->axis()).Union();
501   }
502   flatbuffers::Offset<void> visit(luci::CircleWhere *)
503   {
504     return circle::CreateWhereOptions(_builder).Union();
505   }
506   flatbuffers::Offset<void> visit(luci::CircleWhile *node)
507   {
508     return circle::CreateWhileOptions(_builder, node->cond_branch(), node->body_branch()).Union();
509   }
510   flatbuffers::Offset<void> visit(luci::CircleZerosLike *)
511   {
512     return circle::CreateZerosLikeOptions(_builder).Union();
513   }
514   // Circle only
515   flatbuffers::Offset<void> visit(luci::CircleBCQFullyConnected *node)
516   {
517     return circle::CreateBCQFullyConnectedOptions(
518              _builder, node->weights_hidden_size(),
519              to_circle_actfunc(node->fusedActivationFunction()))
520       .Union();
521   }
522   flatbuffers::Offset<void> visit(luci::CircleBCQGather *node)
523   {
524     return circle::CreateBCQGatherOptions(_builder, node->input_hidden_size(), node->axis())
525       .Union();
526   }
527   flatbuffers::Offset<void> visit(luci::CircleInstanceNorm *node)
528   {
529     return circle::CreateInstanceNormOptions(_builder, node->epsilon(),
530                                              to_circle_actfunc(node->fusedActivationFunction()))
531       .Union();
532   }
533
534 protected:
535   flatbuffers::FlatBufferBuilder &_builder;
536
537 private:
538   const flatbuffers::Offset<void> _no_option = 0;
539 };
540
541 } // namespace luci
542
543 #endif // __CIRCLE_BUILTIN_TYPES_EXTRACTOR_H__