Imported Upstream version 1.9.0
[platform/core/ml/nnfw.git] / compiler / luci / logex / src / FormattedGraph.cpp
1 /*
2  * Copyright (c) 2020 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 #include "luci/FormattedGraph.h"
18
19 #include <luci/IR/CircleDialect.h>
20 #include <luci/IR/CircleNodes.h>
21
22 #include <pepper/str.h>
23
24 #include <cassert>
25 #include <sstream>
26 #include <vector>
27
28 /**
29  * @brief dump std::vector<int64_t> values to stream
30  */
31 std::ostream &operator<<(std::ostream &os, const std::vector<int64_t> &vi64)
32 {
33   for (auto vi : vi64)
34   {
35     os << vi << " ";
36   }
37   return os;
38 }
39
40 // For TF lite
41 namespace
42 {
43
44 const char *to_str(loco::DataType type)
45 {
46   switch (type)
47   {
48     case loco::DataType::U8:
49       return "UINT8";
50     case loco::DataType::U16:
51       return "UINT16";
52     case loco::DataType::U32:
53       return "UINT32";
54     case loco::DataType::U64:
55       return "UINT64";
56
57     case loco::DataType::S8:
58       return "INT8";
59     case loco::DataType::S16:
60       return "INT16";
61     case loco::DataType::S32:
62       return "INT32";
63     case loco::DataType::S64:
64       return "INT64";
65
66     case loco::DataType::FLOAT16:
67       return "FLOAT16";
68     case loco::DataType::FLOAT32:
69       return "FLOAT32";
70     case loco::DataType::FLOAT64:
71       return "FLOAT64";
72
73     case loco::DataType::BOOL:
74       return "BOOL";
75
76     default:
77       return "Error";
78   }
79 }
80
81 const char *to_str(bool value) { return value ? "true" : "false"; }
82
83 const char *to_str(luci::FusedActFunc fused)
84 {
85   switch (fused)
86   {
87     case luci::FusedActFunc::NONE:
88       return "NONE";
89     case luci::FusedActFunc::RELU:
90       return "RELU";
91     case luci::FusedActFunc::RELU_N1_TO_1:
92       return "RELU_N1_TO_1";
93     case luci::FusedActFunc::RELU6:
94       return "RELU6";
95     default:
96       return "Error";
97   }
98 }
99
100 const char *to_str(luci::Padding padding)
101 {
102   switch (padding)
103   {
104     case luci::Padding::SAME:
105       return "SAME";
106     case luci::Padding::VALID:
107       return "VALID";
108     default:
109       return "Error";
110   }
111 }
112
113 const char *to_str(luci::MirrorPadMode mode)
114 {
115   switch (mode)
116   {
117     case luci::MirrorPadMode::REFLECT:
118       return "REFLECT";
119     case luci::MirrorPadMode::SYMMETRIC:
120       return "SYMMETRIC";
121     default:
122       return "Error";
123   }
124 }
125
126 std::string to_str(const luci::Stride *stride)
127 {
128   return pepper::str(stride->h(), ",", stride->w());
129 }
130
131 std::string to_str(const luci::Filter *filter)
132 {
133   return pepper::str(filter->h(), ",", filter->w());
134 }
135
136 std::string circle_opname(uint32_t opnum)
137 {
138   static const std::string prefix{"circle."};
139
140   switch (static_cast<luci::CircleOpcode>(opnum))
141   {
142 #define CIRCLE_NODE(OPCODE, CLASS) \
143   case luci::CircleOpcode::OPCODE: \
144     return prefix + #OPCODE;
145 #include <luci/IR/CircleNodes.lst>
146 #undef CIRCLE_NODE
147     default:
148       break;
149   };
150
151   return prefix + "Invalid";
152 }
153
154 // CircleNodeSummaryBuilder with default implementation
155 class CircleNodeSummaryBuilderBase : public locop::NodeSummaryBuilder
156 {
157 public:
158   CircleNodeSummaryBuilderBase(const locop::SymbolTable *tbl) : _tbl{tbl}
159   {
160     // DO NOTHING
161   }
162
163 public:
164   bool build(const loco::Node *, locop::NodeSummary &s) const final;
165
166 protected:
167 #define CIRCLE_NODE(OPCODE, CLASS)                                      \
168   virtual bool summary(const CLASS *, locop::NodeSummary &s) const      \
169   {                                                                     \
170     s.comments().append("Emitted by Default CircleNodeSummaryBuilder"); \
171     s.state(locop::NodeSummary::State::PartiallyKnown);                 \
172     return true;                                                        \
173   }
174 #include <luci/IR/CircleNodes.lst>
175 #undef CIRCLE_NODE
176
177 protected:
178   const locop::SymbolTable *tbl(void) const { return _tbl; }
179
180   // Please do not use _tbl directly and use tbl().
181   // This will be changed to private in near future.
182 protected:
183   const locop::SymbolTable *_tbl;
184 };
185
186 class CircleNodeSummaryBuilder final : public CircleNodeSummaryBuilderBase
187 {
188 public:
189   CircleNodeSummaryBuilder(const locop::SymbolTable *tbl) : CircleNodeSummaryBuilderBase(tbl)
190   {
191     // DO NOTHING
192   }
193
194 private:
195 #define IMPLEMENT(CLASS) bool summary(const CLASS *, locop::NodeSummary &) const final;
196   IMPLEMENT(luci::CircleAbs)
197   IMPLEMENT(luci::CircleAdd)
198   IMPLEMENT(luci::CircleAddN)
199   IMPLEMENT(luci::CircleArgMax)
200   IMPLEMENT(luci::CircleArgMin)
201   IMPLEMENT(luci::CircleAveragePool2D)
202   IMPLEMENT(luci::CircleBatchMatMul)
203   IMPLEMENT(luci::CircleBatchToSpaceND)
204   IMPLEMENT(luci::CircleCast)
205   IMPLEMENT(luci::CircleCeil)
206   IMPLEMENT(luci::CircleConcatenation)
207   IMPLEMENT(luci::CircleConst)
208   IMPLEMENT(luci::CircleConv2D)
209   IMPLEMENT(luci::CircleCos)
210   IMPLEMENT(luci::CircleCustom)
211   IMPLEMENT(luci::CircleDepthToSpace)
212   IMPLEMENT(luci::CircleDepthwiseConv2D)
213   IMPLEMENT(luci::CircleDiv)
214   IMPLEMENT(luci::CircleElu)
215   IMPLEMENT(luci::CircleExp)
216   IMPLEMENT(luci::CircleExpandDims)
217   IMPLEMENT(luci::CircleFill)
218   IMPLEMENT(luci::CircleFloor)
219   IMPLEMENT(luci::CircleFloorDiv)
220   IMPLEMENT(luci::CircleFloorMod)
221   IMPLEMENT(luci::CircleFullyConnected)
222   IMPLEMENT(luci::CircleGather)
223   IMPLEMENT(luci::CircleGatherNd)
224   IMPLEMENT(luci::CircleGreater)
225   IMPLEMENT(luci::CircleGreaterEqual)
226   IMPLEMENT(luci::CircleIf)
227   IMPLEMENT(luci::CircleL2Normalize)
228   IMPLEMENT(luci::CircleLeakyRelu)
229   IMPLEMENT(luci::CircleLess)
230   IMPLEMENT(luci::CircleLessEqual)
231   IMPLEMENT(luci::CircleLocalResponseNormalization)
232   IMPLEMENT(luci::CircleLog)
233   IMPLEMENT(luci::CircleLogicalAnd)
234   IMPLEMENT(luci::CircleLogicalNot)
235   IMPLEMENT(luci::CircleLogicalOr)
236   IMPLEMENT(luci::CircleLogistic)
237   IMPLEMENT(luci::CircleLogSoftmax)
238   IMPLEMENT(luci::CircleMatrixDiag)
239   IMPLEMENT(luci::CircleMatrixSetDiag)
240   IMPLEMENT(luci::CircleMaximum)
241   IMPLEMENT(luci::CircleMaxPool2D)
242   IMPLEMENT(luci::CircleMean)
243   IMPLEMENT(luci::CircleMinimum)
244   IMPLEMENT(luci::CircleMirrorPad)
245   IMPLEMENT(luci::CircleMul)
246   IMPLEMENT(luci::CircleNeg)
247   IMPLEMENT(luci::CircleNonMaxSuppressionV4)
248   IMPLEMENT(luci::CircleNonMaxSuppressionV5)
249   IMPLEMENT(luci::CircleNotEqual)
250   IMPLEMENT(luci::CircleOneHot)
251   IMPLEMENT(luci::CirclePack)
252   IMPLEMENT(luci::CirclePad)
253   IMPLEMENT(luci::CirclePadV2)
254   IMPLEMENT(luci::CirclePow)
255   IMPLEMENT(luci::CirclePRelu)
256   IMPLEMENT(luci::CircleRange)
257   IMPLEMENT(luci::CircleRank)
258   IMPLEMENT(luci::CircleReduceAny)
259   IMPLEMENT(luci::CircleReduceMax)
260   IMPLEMENT(luci::CircleReduceMin)
261   IMPLEMENT(luci::CircleReduceProd)
262   IMPLEMENT(luci::CircleRelu)
263   IMPLEMENT(luci::CircleRelu6)
264   IMPLEMENT(luci::CircleReluN1To1)
265   IMPLEMENT(luci::CircleReshape)
266   IMPLEMENT(luci::CircleResizeBilinear)
267   IMPLEMENT(luci::CircleResizeNearestNeighbor)
268   IMPLEMENT(luci::CircleReverseSequence)
269   IMPLEMENT(luci::CircleReverseV2)
270   IMPLEMENT(luci::CircleRound)
271   IMPLEMENT(luci::CircleRsqrt)
272   IMPLEMENT(luci::CircleScatterNd)
273   IMPLEMENT(luci::CircleSegmentSum)
274   IMPLEMENT(luci::CircleSelect)
275   IMPLEMENT(luci::CircleSelectV2)
276   IMPLEMENT(luci::CircleShape)
277   IMPLEMENT(luci::CircleSin)
278   IMPLEMENT(luci::CircleSlice)
279   IMPLEMENT(luci::CircleSoftmax)
280   IMPLEMENT(luci::CircleSpaceToBatchND)
281   IMPLEMENT(luci::CircleSpaceToDepth)
282   IMPLEMENT(luci::CircleSparseToDense)
283   IMPLEMENT(luci::CircleSplit)
284   IMPLEMENT(luci::CircleSplitV)
285   IMPLEMENT(luci::CircleSqrt)
286   IMPLEMENT(luci::CircleSquare)
287   IMPLEMENT(luci::CircleSquaredDifference)
288   IMPLEMENT(luci::CircleSqueeze)
289   IMPLEMENT(luci::CircleStridedSlice)
290   IMPLEMENT(luci::CircleSub)
291   IMPLEMENT(luci::CircleSum)
292   IMPLEMENT(luci::CircleTanh)
293   IMPLEMENT(luci::CircleTile)
294   IMPLEMENT(luci::CircleTopKV2)
295   IMPLEMENT(luci::CircleTranspose)
296   IMPLEMENT(luci::CircleTransposeConv)
297   IMPLEMENT(luci::CircleUnique)
298   IMPLEMENT(luci::CircleUnpack)
299   IMPLEMENT(luci::CircleWhere)
300   IMPLEMENT(luci::CircleWhile)
301   IMPLEMENT(luci::CircleZerosLike)
302   // Circle Only
303   IMPLEMENT(luci::CircleBCQFullyConnected)
304   IMPLEMENT(luci::CircleBCQGather)
305   IMPLEMENT(luci::CircleInstanceNorm)
306   // Virtual nodes
307   IMPLEMENT(luci::CircleInput)
308   IMPLEMENT(luci::CircleOutput)
309   IMPLEMENT(luci::CircleIfOut)
310   IMPLEMENT(luci::CircleNonMaxSuppressionV4Out)
311   IMPLEMENT(luci::CircleNonMaxSuppressionV5Out)
312   IMPLEMENT(luci::CircleSplitOut)
313   IMPLEMENT(luci::CircleSplitVOut)
314   IMPLEMENT(luci::CircleTopKV2Out)
315   IMPLEMENT(luci::CircleUniqueOut)
316   IMPLEMENT(luci::CircleUnpackOut)
317   IMPLEMENT(luci::CircleWhileOut)
318 #undef IMPLEMENT
319 };
320
321 template <class CIRCLENODE>
322 bool use_x(const locop::SymbolTable *tbl, const CIRCLENODE *node, locop::NodeSummary &s)
323 {
324   s.args().append("x", tbl->lookup(node->x()));
325   s.state(locop::NodeSummary::State::Complete);
326   return true;
327 }
328
329 template <class CIRCLENODE>
330 bool use_input(const locop::SymbolTable *tbl, const CIRCLENODE *node, locop::NodeSummary &s)
331 {
332   s.args().append("input", tbl->lookup(node->input()));
333   s.state(locop::NodeSummary::State::Complete);
334   return true;
335 }
336
337 template <class CIRCLENODE>
338 bool use_features(const locop::SymbolTable *tbl, const CIRCLENODE *node, locop::NodeSummary &s)
339 {
340   s.args().append("features", tbl->lookup(node->features()));
341   s.state(locop::NodeSummary::State::Complete);
342   return true;
343 }
344
345 template <class CIRCLENODE>
346 bool use_xy(const locop::SymbolTable *tbl, const CIRCLENODE *node, locop::NodeSummary &s)
347 {
348   s.args().append("x", tbl->lookup(node->x()));
349   s.args().append("y", tbl->lookup(node->y()));
350   s.state(locop::NodeSummary::State::Complete);
351   return true;
352 }
353
354 template <class CIRCLENODE>
355 bool use_xy_act(const locop::SymbolTable *tbl, const CIRCLENODE *node, locop::NodeSummary &s)
356 {
357   assert(node->fusedActivationFunction() != luci::FusedActFunc::UNDEFINED);
358
359   s.args().append("x", tbl->lookup(node->x()));
360   s.args().append("y", tbl->lookup(node->y()));
361   s.args().append("fused_activation_function", to_str(node->fusedActivationFunction()));
362   s.state(locop::NodeSummary::State::Complete);
363   return true;
364 }
365
366 template <class CIRCLENODE>
367 bool use_reducer(const locop::SymbolTable *tbl, const CIRCLENODE *node, locop::NodeSummary &s)
368 {
369   s.args().append("input", tbl->lookup(node->input()));
370   s.args().append("reduction_indices", tbl->lookup(node->reduction_indices()));
371   s.args().append("keep_dims", node->keep_dims() ? "true" : "false");
372   s.state(locop::NodeSummary::State::Complete);
373   return true;
374 }
375
376 template <class CIRCLENODE>
377 bool use_ido(const locop::SymbolTable *tbl, const CIRCLENODE *node, locop::NodeSummary &s)
378 {
379   s.args().append("input", tbl->lookup(node->input()));
380   s.args().append("dimension", tbl->lookup(node->dimension()));
381   s.args().append("output_type", to_str(node->output_type()));
382   s.state(locop::NodeSummary::State::Complete);
383   return true;
384 }
385
386 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleAddN *node,
387                   locop::NodeSummary &s)
388 {
389   for (uint32_t i = 0; i < node->arity(); ++i)
390     s.args().append("inputs", tbl->lookup(node->inputs(i)));
391   s.state(locop::NodeSummary::State::Complete);
392   return true;
393 }
394
395 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleAveragePool2D *node,
396                   locop::NodeSummary &s)
397 {
398   assert(node->fusedActivationFunction() != luci::FusedActFunc::UNDEFINED);
399
400   s.args().append("value", tbl->lookup(node->value()));
401   s.args().append("filter(h,w)", to_str(node->filter()));
402   s.args().append("stride(h,w)", to_str(node->stride()));
403   s.args().append("padding", to_str(node->padding()));
404   s.args().append("fused", to_str(node->fusedActivationFunction()));
405   s.state(locop::NodeSummary::State::Complete);
406   return true;
407 }
408
409 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleBatchMatMul *node,
410                   locop::NodeSummary &s)
411 {
412   s.args().append("x", tbl->lookup(node->x()));
413   s.args().append("y", tbl->lookup(node->y()));
414   s.args().append("adj_x", to_str(node->adj_x()));
415   s.args().append("adj_y", to_str(node->adj_y()));
416   s.state(locop::NodeSummary::State::Complete);
417   return true;
418 }
419
420 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleBatchToSpaceND *node,
421                   locop::NodeSummary &s)
422 {
423   s.args().append("input", tbl->lookup(node->input()));
424   s.args().append("block_shape", tbl->lookup(node->block_shape()));
425   s.args().append("crops", tbl->lookup(node->crops()));
426   s.state(locop::NodeSummary::State::Complete);
427   return true;
428 }
429
430 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleCast *node,
431                   locop::NodeSummary &s)
432 {
433   s.args().append("x", tbl->lookup(node->x()));
434   s.args().append("in_data_type", to_str(node->in_data_type()));
435   s.args().append("out_data_type", to_str(node->out_data_type()));
436   s.state(locop::NodeSummary::State::Complete);
437   return true;
438 }
439
440 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleConcatenation *node,
441                   locop::NodeSummary &s)
442 {
443   assert(node->fusedActivationFunction() != luci::FusedActFunc::UNDEFINED);
444
445   for (uint32_t i = 0; i < node->numValues(); ++i)
446     s.args().append("values", tbl->lookup(node->values(i)));
447   s.args().append("axis", pepper::str(node->axis()));
448   s.args().append("fused", to_str(node->fusedActivationFunction()));
449   s.state(locop::NodeSummary::State::Complete);
450   return true;
451 }
452
453 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleConv2D *node,
454                   locop::NodeSummary &s)
455 {
456   assert(node->fusedActivationFunction() != luci::FusedActFunc::UNDEFINED);
457   assert(node->padding() != luci::Padding::UNDEFINED);
458
459   s.args().append("input", tbl->lookup(node->input()));
460   s.args().append("filter", tbl->lookup(node->filter()));
461   s.args().append("bias", tbl->lookup(node->bias()));
462   s.args().append("stride(h,w)", to_str(node->stride()));
463   s.args().append("dilation(h,w)", to_str(node->dilation()));
464   s.args().append("padding", to_str(node->padding()));
465   s.args().append("fused", to_str(node->fusedActivationFunction()));
466   s.state(locop::NodeSummary::State::Complete);
467   return true;
468 }
469
470 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleCustom *node,
471                   locop::NodeSummary &s)
472 {
473   for (uint32_t i = 0; i < node->numInputs(); i++)
474   {
475     s.args().append("input" + std::to_string(i), tbl->lookup(node->inputs(i)));
476   }
477   s.args().append("custom_code", node->custom_code());
478   s.state(locop::NodeSummary::State::Complete);
479   return true;
480 }
481
482 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleDepthToSpace *node,
483                   locop::NodeSummary &s)
484 {
485   s.args().append("input", tbl->lookup(node->input()));
486   s.args().append("block_size", std::to_string(node->block_size()));
487   s.state(locop::NodeSummary::State::Complete);
488   return true;
489 }
490
491 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleDepthwiseConv2D *node,
492                   locop::NodeSummary &s)
493 {
494   assert(node->fusedActivationFunction() != luci::FusedActFunc::UNDEFINED);
495   assert(node->padding() != luci::Padding::UNDEFINED);
496
497   s.args().append("input", tbl->lookup(node->input()));
498   s.args().append("filter", tbl->lookup(node->filter()));
499   s.args().append("bias", tbl->lookup(node->bias()));
500   s.args().append("stride(h,w)", to_str(node->stride()));
501   s.args().append("dilation(h,w)", to_str(node->dilation()));
502   s.args().append("padding", to_str(node->padding()));
503   s.args().append("depthMultiplier", std::to_string(node->depthMultiplier()));
504   s.args().append("fused", to_str(node->fusedActivationFunction()));
505   s.state(locop::NodeSummary::State::Complete);
506   return true;
507 }
508
509 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleExpandDims *node,
510                   locop::NodeSummary &s)
511 {
512   s.args().append("input", tbl->lookup(node->input()));
513   s.args().append("axis", tbl->lookup(node->axis()));
514   s.state(locop::NodeSummary::State::Complete);
515   return true;
516 }
517
518 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleFill *node,
519                   locop::NodeSummary &s)
520 {
521   s.args().append("dims", tbl->lookup(node->dims()));
522   s.args().append("value", tbl->lookup(node->value()));
523   s.state(locop::NodeSummary::State::Complete);
524   return true;
525 }
526
527 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleFullyConnected *node,
528                   locop::NodeSummary &s)
529 {
530   assert(node->fusedActivationFunction() != luci::FusedActFunc::UNDEFINED);
531
532   s.args().append("input", tbl->lookup(node->input()));
533   s.args().append("weights", tbl->lookup(node->weights()));
534   s.args().append("bias", tbl->lookup(node->bias()));
535   s.args().append("fused", to_str(node->fusedActivationFunction()));
536   s.state(locop::NodeSummary::State::Complete);
537   return true;
538 }
539
540 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleGather *node,
541                   locop::NodeSummary &s)
542 {
543   s.args().append("params", tbl->lookup(node->params()));
544   s.args().append("indices", tbl->lookup(node->indices()));
545   s.args().append("axis", pepper::str(node->axis()));
546   s.state(locop::NodeSummary::State::Complete);
547   return true;
548 }
549
550 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleGatherNd *node,
551                   locop::NodeSummary &s)
552 {
553   s.args().append("params", tbl->lookup(node->params()));
554   s.args().append("indices", tbl->lookup(node->indices()));
555   s.state(locop::NodeSummary::State::Complete);
556   return true;
557 }
558
559 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleIf *node, locop::NodeSummary &s)
560 {
561   s.args().append("cond", tbl->lookup(node->cond()));
562   for (uint32_t i = 0; i < node->input_count(); ++i)
563     s.args().append("input", tbl->lookup(node->input(i)));
564
565   if (node->then_graph() != nullptr)
566     s.args().append("then_graph", node->then_graph()->name());
567   else
568     s.args().append("then_branch", pepper::str(node->then_branch()));
569
570   if (node->else_graph() != nullptr)
571     s.args().append("else_graph", node->else_graph()->name());
572   else
573     s.args().append("else_branch", pepper::str(node->else_branch()));
574
575   s.state(locop::NodeSummary::State::Complete);
576   return true;
577 }
578
579 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleL2Normalize *node,
580                   locop::NodeSummary &s)
581 {
582   s.args().append("x", tbl->lookup(node->x()));
583   s.args().append("fused_activation_function", to_str(node->fusedActivationFunction()));
584   s.state(locop::NodeSummary::State::Complete);
585   return true;
586 }
587
588 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleLeakyRelu *node,
589                   locop::NodeSummary &s)
590 {
591   s.args().append("features", tbl->lookup(node->features()));
592   s.args().append("alpha", std::to_string(node->alpha()));
593   s.state(locop::NodeSummary::State::Complete);
594   return true;
595 }
596
597 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleLocalResponseNormalization *node,
598                   locop::NodeSummary &s)
599 {
600   s.args().append("input", tbl->lookup(node->input()));
601   s.args().append("radius", pepper::str(node->radius()));
602   s.args().append("bias", pepper::str(node->bias()));
603   s.args().append("alpha", pepper::str(node->alpha()));
604   s.args().append("beta", pepper::str(node->beta()));
605   s.state(locop::NodeSummary::State::Complete);
606   return true;
607 }
608
609 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleLogSoftmax *node,
610                   locop::NodeSummary &s)
611 {
612   s.args().append("logits", tbl->lookup(node->logits()));
613   s.state(locop::NodeSummary::State::Complete);
614   return true;
615 }
616
617 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleMatrixDiag *node,
618                   locop::NodeSummary &s)
619 {
620   s.args().append("diagonal", tbl->lookup(node->diagonal()));
621   s.state(locop::NodeSummary::State::Complete);
622   return true;
623 }
624
625 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleMatrixSetDiag *node,
626                   locop::NodeSummary &s)
627 {
628   s.args().append("input", tbl->lookup(node->input()));
629   s.args().append("diagonal", tbl->lookup(node->diagonal()));
630   s.state(locop::NodeSummary::State::Complete);
631   return true;
632 }
633
634 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleMaxPool2D *node,
635                   locop::NodeSummary &s)
636 {
637   assert(node->fusedActivationFunction() != luci::FusedActFunc::UNDEFINED);
638
639   s.args().append("value", tbl->lookup(node->value()));
640   s.args().append("filter(h,w)", to_str(node->filter()));
641   s.args().append("stride(h,w)", to_str(node->stride()));
642   s.args().append("padding", to_str(node->padding()));
643   s.args().append("fused", to_str(node->fusedActivationFunction()));
644   s.state(locop::NodeSummary::State::Complete);
645   return true;
646 }
647
648 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleMirrorPad *node,
649                   locop::NodeSummary &s)
650 {
651   s.args().append("input", tbl->lookup(node->input()));
652   s.args().append("paddings", tbl->lookup(node->paddings()));
653   s.args().append("mode", to_str(node->mode()));
654   s.state(locop::NodeSummary::State::Complete);
655   return true;
656 }
657
658 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleNonMaxSuppressionV4 *node,
659                   locop::NodeSummary &s)
660 {
661   s.args().append("boxes", tbl->lookup(node->boxes()));
662   s.args().append("scores", tbl->lookup(node->scores()));
663   s.args().append("max_output_size", tbl->lookup(node->max_output_size()));
664   s.args().append("iou_threshold", tbl->lookup(node->iou_threshold()));
665   s.args().append("score_threshold", tbl->lookup(node->score_threshold()));
666   s.state(locop::NodeSummary::State::Complete);
667   return true;
668 }
669
670 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleNonMaxSuppressionV5 *node,
671                   locop::NodeSummary &s)
672 {
673   s.args().append("boxes", tbl->lookup(node->boxes()));
674   s.args().append("scores", tbl->lookup(node->scores()));
675   s.args().append("max_output_size", tbl->lookup(node->max_output_size()));
676   s.args().append("iou_threshold", tbl->lookup(node->iou_threshold()));
677   s.args().append("score_threshold", tbl->lookup(node->score_threshold()));
678   s.args().append("soft_nms_sigma", tbl->lookup(node->soft_nms_sigma()));
679   s.state(locop::NodeSummary::State::Complete);
680   return true;
681 }
682
683 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleOneHot *node,
684                   locop::NodeSummary &s)
685 {
686   s.args().append("indices", tbl->lookup(node->indices()));
687   s.args().append("depth", tbl->lookup(node->depth()));
688   s.args().append("on_value", tbl->lookup(node->on_value()));
689   s.args().append("off_value", tbl->lookup(node->off_value()));
690   s.args().append("axis", pepper::str(node->axis()));
691
692   s.state(locop::NodeSummary::State::Complete);
693   return true;
694 }
695
696 bool summary_node(const locop::SymbolTable *tbl, const luci::CirclePack *node,
697                   locop::NodeSummary &s)
698 {
699   for (uint32_t i = 0; i < node->values_count(); ++i)
700     s.args().append("values", tbl->lookup(node->values(i)));
701   s.args().append("values_count", pepper::str(node->values_count()));
702   s.args().append("axis", pepper::str(node->axis()));
703   s.state(locop::NodeSummary::State::Complete);
704   return true;
705 }
706
707 bool summary_node(const locop::SymbolTable *tbl, const luci::CirclePad *node, locop::NodeSummary &s)
708 {
709   s.args().append("input", tbl->lookup(node->input()));
710   s.args().append("paddings", tbl->lookup(node->paddings()));
711   s.state(locop::NodeSummary::State::Complete);
712   return true;
713 }
714
715 bool summary_node(const locop::SymbolTable *tbl, const luci::CirclePadV2 *node,
716                   locop::NodeSummary &s)
717 {
718   s.args().append("input", tbl->lookup(node->input()));
719   s.args().append("paddings", tbl->lookup(node->paddings()));
720   s.args().append("constant_values", tbl->lookup(node->constant_values()));
721   s.state(locop::NodeSummary::State::Complete);
722   return true;
723 }
724
725 bool summary_node(const locop::SymbolTable *tbl, const luci::CirclePRelu *node,
726                   locop::NodeSummary &s)
727 {
728   s.args().append("input", tbl->lookup(node->input()));
729   s.args().append("alpha", tbl->lookup(node->alpha()));
730   s.state(locop::NodeSummary::State::Complete);
731   return true;
732 }
733
734 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleRange *node,
735                   locop::NodeSummary &s)
736 {
737   s.args().append("start", tbl->lookup(node->start()));
738   s.args().append("limit", tbl->lookup(node->limit()));
739   s.args().append("delta", tbl->lookup(node->delta()));
740   s.state(locop::NodeSummary::State::Complete);
741   return true;
742 }
743
744 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleReshape *node,
745                   locop::NodeSummary &s)
746 {
747   s.args().append("tensor", tbl->lookup(node->tensor()));
748   s.args().append("shape", tbl->lookup(node->shape()));
749   // TODO Show newShape info
750   s.state(locop::NodeSummary::State::PartiallyKnown);
751   return true;
752 }
753
754 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleResizeBilinear *node,
755                   locop::NodeSummary &s)
756 {
757   s.args().append("input", tbl->lookup(node->input()));
758   s.args().append("size", tbl->lookup(node->size()));
759   s.args().append("align_corners", node->align_corners() ? "true" : "false");
760   s.args().append("half_pixel_centers", node->half_pixel_centers() ? "true" : "false");
761   s.state(locop::NodeSummary::State::Complete);
762   return true;
763 }
764
765 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleResizeNearestNeighbor *node,
766                   locop::NodeSummary &s)
767 {
768   s.args().append("input", tbl->lookup(node->input()));
769   s.args().append("size", tbl->lookup(node->size()));
770   s.args().append("align_corners", node->align_corners() ? "true" : "false");
771   s.state(locop::NodeSummary::State::Complete);
772   return true;
773 }
774
775 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleReverseSequence *node,
776                   locop::NodeSummary &s)
777 {
778   s.args().append("input", tbl->lookup(node->input()));
779   s.args().append("seq_lengths", tbl->lookup(node->seq_lengths()));
780   s.args().append("seq_axis", std::to_string(node->seq_axis()));
781   s.args().append("batch_axis", std::to_string(node->batch_axis()));
782   s.state(locop::NodeSummary::State::Complete);
783   return true;
784 }
785
786 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleReverseV2 *node,
787                   locop::NodeSummary &s)
788 {
789   s.args().append("tensor", tbl->lookup(node->tensor()));
790   s.args().append("axis", tbl->lookup(node->axis()));
791   s.state(locop::NodeSummary::State::Complete);
792   return true;
793 }
794
795 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleScatterNd *node,
796                   locop::NodeSummary &s)
797 {
798   s.args().append("indices", tbl->lookup(node->indices()));
799   s.args().append("updates", tbl->lookup(node->updates()));
800   s.args().append("shape", tbl->lookup(node->shape()));
801   s.state(locop::NodeSummary::State::Complete);
802   return true;
803 }
804
805 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleSegmentSum *node,
806                   locop::NodeSummary &s)
807 {
808   s.args().append("input", tbl->lookup(node->input()));
809   s.args().append("segment_ids", tbl->lookup(node->segment_ids()));
810   s.state(locop::NodeSummary::State::Complete);
811   return true;
812 }
813
814 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleSelect *node,
815                   locop::NodeSummary &s)
816 {
817   s.args().append("condition", tbl->lookup(node->condition()));
818   s.args().append("t", tbl->lookup(node->t()));
819   s.args().append("e", tbl->lookup(node->e()));
820   s.state(locop::NodeSummary::State::Complete);
821   return true;
822 }
823
824 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleSelectV2 *node,
825                   locop::NodeSummary &s)
826 {
827   s.args().append("condition", tbl->lookup(node->condition()));
828   s.args().append("t", tbl->lookup(node->t()));
829   s.args().append("e", tbl->lookup(node->e()));
830   s.state(locop::NodeSummary::State::Complete);
831   return true;
832 }
833
834 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleShape *node,
835                   locop::NodeSummary &s)
836 {
837   s.args().append("input", tbl->lookup(node->input()));
838   s.args().append("out_type", to_str(node->out_type()));
839   s.state(locop::NodeSummary::State::Complete);
840   return true;
841 }
842
843 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleSlice *node,
844                   locop::NodeSummary &s)
845 {
846   s.args().append("input", tbl->lookup(node->input()));
847   s.args().append("begin", tbl->lookup(node->begin()));
848   s.args().append("size", tbl->lookup(node->size()));
849   s.state(locop::NodeSummary::State::Complete);
850   return true;
851 }
852
853 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleSoftmax *node,
854                   locop::NodeSummary &s)
855 {
856   s.args().append("logits", tbl->lookup(node->logits()));
857   s.args().append("beta", pepper::str(node->beta()));
858   s.state(locop::NodeSummary::State::Complete);
859   return true;
860 }
861
862 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleSpaceToBatchND *node,
863                   locop::NodeSummary &s)
864 {
865   s.args().append("input", tbl->lookup(node->input()));
866   s.args().append("block_shape", tbl->lookup(node->block_shape()));
867   s.args().append("paddings", tbl->lookup(node->paddings()));
868   s.state(locop::NodeSummary::State::Complete);
869   return true;
870 }
871
872 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleSpaceToDepth *node,
873                   locop::NodeSummary &s)
874 {
875   s.args().append("input", tbl->lookup(node->input()));
876   s.args().append("block_size", pepper::str(node->block_size()));
877   s.state(locop::NodeSummary::State::Complete);
878   return true;
879 }
880
881 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleSparseToDense *node,
882                   locop::NodeSummary &s)
883 {
884   s.args().append("indices", tbl->lookup(node->indices()));
885   s.args().append("output_shape", tbl->lookup(node->output_shape()));
886   s.args().append("values", tbl->lookup(node->values()));
887   s.args().append("default_value", tbl->lookup(node->default_value()));
888   s.args().append("Validate_indices", pepper::str(node->validate_indices()));
889   s.state(locop::NodeSummary::State::Complete);
890   return true;
891 }
892
893 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleSplit *node,
894                   locop::NodeSummary &s)
895 {
896   s.args().append("split_dim", tbl->lookup(node->split_dim()));
897   s.args().append("input", tbl->lookup(node->input()));
898   s.args().append("num_split", pepper::str(node->num_split()));
899   s.state(locop::NodeSummary::State::Complete);
900   return true;
901 }
902
903 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleSplitV *node,
904                   locop::NodeSummary &s)
905 {
906   s.args().append("input", tbl->lookup(node->input()));
907   s.args().append("size_splits", tbl->lookup(node->size_splits()));
908   s.args().append("split_dim", tbl->lookup(node->split_dim()));
909   s.args().append("num_split", pepper::str(node->num_split()));
910   s.state(locop::NodeSummary::State::Complete);
911   return true;
912 }
913
914 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleSqueeze *node,
915                   locop::NodeSummary &s)
916 {
917   s.args().append("input", tbl->lookup(node->input()));
918
919   std::stringstream ss{"("};
920   for (size_t i = 0; i < node->squeeze_dims().size(); ++i)
921   {
922     if (i != 0)
923       ss << ", ";
924     ss << node->squeeze_dims()[i];
925   }
926   ss << ")";
927   s.args().append("squeeze_dims", ss.str());
928   s.state(locop::NodeSummary::State::Complete);
929   return true;
930 }
931
932 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleStridedSlice *node,
933                   locop::NodeSummary &s)
934 {
935   s.args().append("input", tbl->lookup(node->input()));
936   s.args().append("begin", tbl->lookup(node->begin()));
937   s.args().append("end", tbl->lookup(node->end()));
938   s.args().append("strides", tbl->lookup(node->strides()));
939   s.args().append("begin_mask", pepper::str(node->begin_mask()));
940   s.args().append("end_mask", pepper::str(node->end_mask()));
941   s.args().append("ellipsis_mask", pepper::str(node->ellipsis_mask()));
942   s.args().append("new_axis_mask", pepper::str(node->new_axis_mask()));
943   s.args().append("shrink_axis_mask", pepper::str(node->shrink_axis_mask()));
944   s.state(locop::NodeSummary::State::Complete);
945   return true;
946 }
947
948 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleTile *node,
949                   locop::NodeSummary &s)
950 {
951   s.args().append("input", tbl->lookup(node->input()));
952   s.args().append("multiples", tbl->lookup(node->multiples()));
953   s.state(locop::NodeSummary::State::Complete);
954   return true;
955 }
956
957 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleTopKV2 *node,
958                   locop::NodeSummary &s)
959 {
960   s.args().append("input", tbl->lookup(node->input()));
961   s.args().append("k", tbl->lookup(node->k()));
962   s.state(locop::NodeSummary::State::Complete);
963   return true;
964 }
965
966 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleTranspose *node,
967                   locop::NodeSummary &s)
968 {
969   s.args().append("a", tbl->lookup(node->a()));
970   s.args().append("perm", tbl->lookup(node->perm()));
971   s.state(locop::NodeSummary::State::Complete);
972   return true;
973 }
974
975 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleTransposeConv *node,
976                   locop::NodeSummary &s)
977 {
978   assert(node->padding() != luci::Padding::UNDEFINED);
979
980   s.args().append("inputSizes", tbl->lookup(node->inputSizes()));
981   s.args().append("filter", tbl->lookup(node->filter()));
982   s.args().append("outBackprop", tbl->lookup(node->outBackprop()));
983   s.args().append("stride(h,w)", to_str(node->stride()));
984   s.args().append("padding", to_str(node->padding()));
985   s.state(locop::NodeSummary::State::Complete);
986   return true;
987 }
988
989 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleUnique *node,
990                   locop::NodeSummary &s)
991 {
992   s.args().append("input", tbl->lookup(node->input()));
993   s.args().append("idx_out_type", to_str(node->idx_out_type()));
994   s.state(locop::NodeSummary::State::Complete);
995   return true;
996 }
997
998 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleUnpack *node,
999                   locop::NodeSummary &s)
1000 {
1001   s.args().append("value", tbl->lookup(node->value()));
1002   s.args().append("num", pepper::str(node->num()));
1003   s.args().append("axis", pepper::str(node->axis()));
1004   s.state(locop::NodeSummary::State::Complete);
1005   return true;
1006 }
1007
1008 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleWhere *node,
1009                   locop::NodeSummary &s)
1010 {
1011   s.args().append("condition", tbl->lookup(node->condition()));
1012   s.state(locop::NodeSummary::State::Complete);
1013   return true;
1014 }
1015
1016 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleWhile *node,
1017                   locop::NodeSummary &s)
1018 {
1019   for (uint32_t i = 0; i < node->input_count(); ++i)
1020     s.args().append("input", tbl->lookup(node->input(i)));
1021
1022   if (node->cond_graph() != nullptr)
1023     s.args().append("cond_graph", node->cond_graph()->name());
1024   else
1025     s.args().append("cond_branch", pepper::str(node->cond_branch()));
1026
1027   if (node->body_graph() != nullptr)
1028     s.args().append("body_graph", node->body_graph()->name());
1029   else
1030     s.args().append("body_branch", pepper::str(node->body_branch()));
1031
1032   s.state(locop::NodeSummary::State::Complete);
1033   return true;
1034 }
1035
1036 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleTopKV2Out *node,
1037                   locop::NodeSummary &s)
1038 {
1039   s.args().append("topkv2", tbl->lookup(node->input()));
1040   s.state(locop::NodeSummary::State::Complete);
1041   return true;
1042 }
1043
1044 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleUniqueOut *node,
1045                   locop::NodeSummary &s)
1046 {
1047   s.args().append("unique", tbl->lookup(node->input()));
1048   s.state(locop::NodeSummary::State::Complete);
1049   return true;
1050 }
1051
1052 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleUnpackOut *node,
1053                   locop::NodeSummary &s)
1054 {
1055   s.args().append("unpack", tbl->lookup(node->input()));
1056   s.state(locop::NodeSummary::State::Complete);
1057   return true;
1058 }
1059
1060 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleWhileOut *node,
1061                   locop::NodeSummary &s)
1062 {
1063   s.args().append("while", tbl->lookup(node->input()));
1064   s.state(locop::NodeSummary::State::Complete);
1065   return true;
1066 }
1067
1068 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleOutput *node,
1069                   locop::NodeSummary &s)
1070 {
1071   s.args().append("from", tbl->lookup(node->from()));
1072   s.state(locop::NodeSummary::State::Complete);
1073   return true;
1074 }
1075
1076 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleBCQFullyConnected *node,
1077                   locop::NodeSummary &s)
1078 {
1079   assert(node->fusedActivationFunction() != luci::FusedActFunc::UNDEFINED);
1080   s.args().append("input", tbl->lookup(node->input()));
1081   s.args().append("weights_scales", tbl->lookup(node->weights_scales()));
1082   s.args().append("weights_binary", tbl->lookup(node->weights_binary()));
1083   s.args().append("bias", tbl->lookup(node->bias()));
1084   s.args().append("weights_clusters", tbl->lookup(node->weights_clusters()));
1085   s.args().append("fused", to_str(node->fusedActivationFunction()));
1086   s.args().append("weights_hidden_size", pepper::str(node->weights_hidden_size()));
1087   s.state(locop::NodeSummary::State::Complete);
1088   return true;
1089 }
1090
1091 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleBCQGather *node,
1092                   locop::NodeSummary &s)
1093 {
1094   s.args().append("input_scales", tbl->lookup(node->input_scales()));
1095   s.args().append("input_binary", tbl->lookup(node->input_binary()));
1096   s.args().append("indices", tbl->lookup(node->indices()));
1097   s.args().append("input_clusters", tbl->lookup(node->input_clusters()));
1098   s.args().append("axis", pepper::str(node->axis()));
1099   s.args().append("input_hidden_size", pepper::str(node->input_hidden_size()));
1100   s.state(locop::NodeSummary::State::Complete);
1101   return true;
1102 }
1103
1104 bool summary_node(const locop::SymbolTable *tbl, const luci::CircleInstanceNorm *node,
1105                   locop::NodeSummary &s)
1106 {
1107   auto fused = node->fusedActivationFunction();
1108   assert(fused != luci::FusedActFunc::UNDEFINED);
1109
1110   s.args().append("input", tbl->lookup(node->input()));
1111   s.args().append("gamma", tbl->lookup(node->gamma()));
1112   s.args().append("beta", tbl->lookup(node->beta()));
1113   s.args().append("epsilon", pepper::str(node->epsilon()));
1114   s.args().append("fused_activation_function", to_str(fused));
1115   s.state(locop::NodeSummary::State::Complete);
1116   return true;
1117 }
1118
1119 bool CircleNodeSummaryBuilderBase::build(const loco::Node *node, locop::NodeSummary &s) const
1120 {
1121   if (node->dialect() != luci::CircleDialect::get())
1122     return false;
1123
1124 #define CIRCLE_NODE(OPCODE, CLASS)                        \
1125   if (dynamic_cast<const CLASS *>(node))                  \
1126   {                                                       \
1127     s.opname(circle_opname(node->opnum()));               \
1128     return summary(dynamic_cast<const CLASS *>(node), s); \
1129   }
1130 #include <luci/IR/CircleNodes.lst>
1131 #undef CIRCLE_NODE
1132
1133   return false;
1134 }
1135
1136 bool CircleNodeSummaryBuilder::summary(const luci::CircleAbs *node, locop::NodeSummary &s) const
1137 {
1138   return use_x(tbl(), node, s);
1139 }
1140
1141 bool CircleNodeSummaryBuilder::summary(const luci::CircleAdd *node, locop::NodeSummary &s) const
1142 {
1143   return use_xy_act(tbl(), node, s);
1144 }
1145
1146 bool CircleNodeSummaryBuilder::summary(const luci::CircleAddN *node, locop::NodeSummary &s) const
1147 {
1148   return summary_node(tbl(), node, s);
1149 }
1150
1151 bool CircleNodeSummaryBuilder::summary(const luci::CircleArgMax *node, locop::NodeSummary &s) const
1152 {
1153   return use_ido(tbl(), node, s);
1154 }
1155
1156 bool CircleNodeSummaryBuilder::summary(const luci::CircleArgMin *node, locop::NodeSummary &s) const
1157 {
1158   return use_ido(tbl(), node, s);
1159 }
1160
1161 bool CircleNodeSummaryBuilder::summary(const luci::CircleAveragePool2D *node,
1162                                        locop::NodeSummary &s) const
1163 {
1164   return summary_node(tbl(), node, s);
1165 }
1166
1167 bool CircleNodeSummaryBuilder::summary(const luci::CircleBatchMatMul *node,
1168                                        locop::NodeSummary &s) const
1169 {
1170   return summary_node(tbl(), node, s);
1171 }
1172
1173 bool CircleNodeSummaryBuilder::summary(const luci::CircleBatchToSpaceND *node,
1174                                        locop::NodeSummary &s) const
1175 {
1176   return summary_node(tbl(), node, s);
1177 }
1178
1179 bool CircleNodeSummaryBuilder::summary(const luci::CircleCast *node, locop::NodeSummary &s) const
1180 {
1181   return summary_node(tbl(), node, s);
1182 }
1183
1184 bool CircleNodeSummaryBuilder::summary(const luci::CircleCeil *node, locop::NodeSummary &s) const
1185 {
1186   return use_x(tbl(), node, s);
1187 }
1188
1189 bool CircleNodeSummaryBuilder::summary(const luci::CircleConcatenation *node,
1190                                        locop::NodeSummary &s) const
1191 {
1192   return summary_node(tbl(), node, s);
1193 }
1194
1195 bool CircleNodeSummaryBuilder::summary(const luci::CircleConst *, locop::NodeSummary &s) const
1196 {
1197   s.state(locop::NodeSummary::State::PartiallyKnown);
1198   return true;
1199 }
1200
1201 bool CircleNodeSummaryBuilder::summary(const luci::CircleConv2D *node, locop::NodeSummary &s) const
1202 {
1203   return summary_node(tbl(), node, s);
1204 }
1205
1206 bool CircleNodeSummaryBuilder::summary(const luci::CircleCos *node, locop::NodeSummary &s) const
1207 {
1208   return use_x(tbl(), node, s);
1209 }
1210
1211 bool CircleNodeSummaryBuilder::summary(const luci::CircleCustom *node, locop::NodeSummary &s) const
1212 {
1213   return summary_node(tbl(), node, s);
1214 }
1215
1216 bool CircleNodeSummaryBuilder::summary(const luci::CircleDepthToSpace *node,
1217                                        locop::NodeSummary &s) const
1218 {
1219   return summary_node(tbl(), node, s);
1220 }
1221
1222 bool CircleNodeSummaryBuilder::summary(const luci::CircleDepthwiseConv2D *node,
1223                                        locop::NodeSummary &s) const
1224 {
1225   return summary_node(tbl(), node, s);
1226 }
1227
1228 bool CircleNodeSummaryBuilder::summary(const luci::CircleDiv *node, locop::NodeSummary &s) const
1229 {
1230   return use_xy(tbl(), node, s);
1231 }
1232
1233 bool CircleNodeSummaryBuilder::summary(const luci::CircleElu *node, locop::NodeSummary &s) const
1234 {
1235   return use_features(tbl(), node, s);
1236 }
1237
1238 bool CircleNodeSummaryBuilder::summary(const luci::CircleExp *node, locop::NodeSummary &s) const
1239 {
1240   return use_x(tbl(), node, s);
1241 }
1242
1243 bool CircleNodeSummaryBuilder::summary(const luci::CircleExpandDims *node,
1244                                        locop::NodeSummary &s) const
1245 {
1246   return summary_node(tbl(), node, s);
1247 }
1248
1249 bool CircleNodeSummaryBuilder::summary(const luci::CircleFloor *node, locop::NodeSummary &s) const
1250 {
1251   return use_x(tbl(), node, s);
1252 }
1253
1254 bool CircleNodeSummaryBuilder::summary(const luci::CircleFloorDiv *node,
1255                                        locop::NodeSummary &s) const
1256 {
1257   return use_xy(tbl(), node, s);
1258 }
1259
1260 bool CircleNodeSummaryBuilder::summary(const luci::CircleFloorMod *node,
1261                                        locop::NodeSummary &s) const
1262 {
1263   return use_xy(tbl(), node, s);
1264 }
1265
1266 bool CircleNodeSummaryBuilder::summary(const luci::CircleFill *node, locop::NodeSummary &s) const
1267 {
1268   return summary_node(tbl(), node, s);
1269 }
1270
1271 bool CircleNodeSummaryBuilder::summary(const luci::CircleFullyConnected *node,
1272                                        locop::NodeSummary &s) const
1273 {
1274   return summary_node(tbl(), node, s);
1275 }
1276
1277 bool CircleNodeSummaryBuilder::summary(const luci::CircleGather *node, locop::NodeSummary &s) const
1278 {
1279   return summary_node(tbl(), node, s);
1280 }
1281
1282 bool CircleNodeSummaryBuilder::summary(const luci::CircleGatherNd *node,
1283                                        locop::NodeSummary &s) const
1284 {
1285   return summary_node(tbl(), node, s);
1286 }
1287
1288 bool CircleNodeSummaryBuilder::summary(const luci::CircleGreater *node, locop::NodeSummary &s) const
1289 {
1290   return use_xy(tbl(), node, s);
1291 }
1292
1293 bool CircleNodeSummaryBuilder::summary(const luci::CircleGreaterEqual *node,
1294                                        locop::NodeSummary &s) const
1295 {
1296   return use_xy(tbl(), node, s);
1297 }
1298
1299 bool CircleNodeSummaryBuilder::summary(const luci::CircleIf *node, locop::NodeSummary &s) const
1300 {
1301   return summary_node(tbl(), node, s);
1302 }
1303
1304 bool CircleNodeSummaryBuilder::summary(const luci::CircleL2Normalize *node,
1305                                        locop::NodeSummary &s) const
1306 {
1307   return summary_node(tbl(), node, s);
1308 }
1309
1310 bool CircleNodeSummaryBuilder::summary(const luci::CircleLess *node, locop::NodeSummary &s) const
1311 {
1312   return use_xy(tbl(), node, s);
1313 }
1314
1315 bool CircleNodeSummaryBuilder::summary(const luci::CircleLessEqual *node,
1316                                        locop::NodeSummary &s) const
1317 {
1318   return use_xy(tbl(), node, s);
1319 }
1320
1321 bool CircleNodeSummaryBuilder::summary(const luci::CircleLeakyRelu *node,
1322                                        locop::NodeSummary &s) const
1323 {
1324   return summary_node(tbl(), node, s);
1325 }
1326
1327 bool CircleNodeSummaryBuilder::summary(const luci::CircleLocalResponseNormalization *node,
1328                                        locop::NodeSummary &s) const
1329 {
1330   return summary_node(tbl(), node, s);
1331 }
1332
1333 bool CircleNodeSummaryBuilder::summary(const luci::CircleLog *node, locop::NodeSummary &s) const
1334 {
1335   return use_x(tbl(), node, s);
1336 }
1337
1338 bool CircleNodeSummaryBuilder::summary(const luci::CircleLogicalAnd *node,
1339                                        locop::NodeSummary &s) const
1340 {
1341   return use_xy(tbl(), node, s);
1342 }
1343
1344 bool CircleNodeSummaryBuilder::summary(const luci::CircleLogicalNot *node,
1345                                        locop::NodeSummary &s) const
1346 {
1347   return use_x(tbl(), node, s);
1348 }
1349
1350 bool CircleNodeSummaryBuilder::summary(const luci::CircleLogicalOr *node,
1351                                        locop::NodeSummary &s) const
1352 {
1353   return use_xy(tbl(), node, s);
1354 }
1355
1356 bool CircleNodeSummaryBuilder::summary(const luci::CircleLogistic *node,
1357                                        locop::NodeSummary &s) const
1358 {
1359   return use_x(tbl(), node, s);
1360 }
1361
1362 bool CircleNodeSummaryBuilder::summary(const luci::CircleLogSoftmax *node,
1363                                        locop::NodeSummary &s) const
1364 {
1365   return summary_node(tbl(), node, s);
1366 }
1367
1368 bool CircleNodeSummaryBuilder::summary(const luci::CircleMatrixDiag *node,
1369                                        locop::NodeSummary &s) const
1370 {
1371   return summary_node(tbl(), node, s);
1372 }
1373
1374 bool CircleNodeSummaryBuilder::summary(const luci::CircleMatrixSetDiag *node,
1375                                        locop::NodeSummary &s) const
1376 {
1377   return summary_node(tbl(), node, s);
1378 }
1379
1380 bool CircleNodeSummaryBuilder::summary(const luci::CircleMaximum *node, locop::NodeSummary &s) const
1381 {
1382   return use_xy(tbl(), node, s);
1383 }
1384
1385 bool CircleNodeSummaryBuilder::summary(const luci::CircleMaxPool2D *node,
1386                                        locop::NodeSummary &s) const
1387 {
1388   return summary_node(tbl(), node, s);
1389 }
1390
1391 bool CircleNodeSummaryBuilder::summary(const luci::CircleMean *node, locop::NodeSummary &s) const
1392 {
1393   return use_reducer(tbl(), node, s);
1394 }
1395
1396 bool CircleNodeSummaryBuilder::summary(const luci::CircleMinimum *node, locop::NodeSummary &s) const
1397 {
1398   return use_xy(tbl(), node, s);
1399 }
1400
1401 bool CircleNodeSummaryBuilder::summary(const luci::CircleMirrorPad *node,
1402                                        locop::NodeSummary &s) const
1403 {
1404   return summary_node(tbl(), node, s);
1405 }
1406
1407 bool CircleNodeSummaryBuilder::summary(const luci::CircleMul *node, locop::NodeSummary &s) const
1408 {
1409   return use_xy_act(tbl(), node, s);
1410 }
1411
1412 bool CircleNodeSummaryBuilder::summary(const luci::CircleNeg *node, locop::NodeSummary &s) const
1413 {
1414   return use_x(tbl(), node, s);
1415 }
1416
1417 bool CircleNodeSummaryBuilder::summary(const luci::CircleNonMaxSuppressionV4 *node,
1418                                        locop::NodeSummary &s) const
1419 {
1420   return summary_node(tbl(), node, s);
1421 }
1422
1423 bool CircleNodeSummaryBuilder::summary(const luci::CircleNonMaxSuppressionV5 *node,
1424                                        locop::NodeSummary &s) const
1425 {
1426   return summary_node(tbl(), node, s);
1427 }
1428
1429 bool CircleNodeSummaryBuilder::summary(const luci::CircleNotEqual *node,
1430                                        locop::NodeSummary &s) const
1431 {
1432   return use_xy(tbl(), node, s);
1433 }
1434
1435 bool CircleNodeSummaryBuilder::summary(const luci::CircleOneHot *node, locop::NodeSummary &s) const
1436 {
1437   return summary_node(tbl(), node, s);
1438 }
1439
1440 bool CircleNodeSummaryBuilder::summary(const luci::CirclePack *node, locop::NodeSummary &s) const
1441 {
1442   return summary_node(tbl(), node, s);
1443 }
1444
1445 bool CircleNodeSummaryBuilder::summary(const luci::CirclePad *node, locop::NodeSummary &s) const
1446 {
1447   return summary_node(tbl(), node, s);
1448 }
1449
1450 bool CircleNodeSummaryBuilder::summary(const luci::CirclePadV2 *node, locop::NodeSummary &s) const
1451 {
1452   return summary_node(tbl(), node, s);
1453 }
1454
1455 bool CircleNodeSummaryBuilder::summary(const luci::CirclePow *node, locop::NodeSummary &s) const
1456 {
1457   return use_xy(tbl(), node, s);
1458 }
1459
1460 bool CircleNodeSummaryBuilder::summary(const luci::CirclePRelu *node, locop::NodeSummary &s) const
1461 {
1462   return summary_node(tbl(), node, s);
1463 }
1464
1465 bool CircleNodeSummaryBuilder::summary(const luci::CircleRange *node, locop::NodeSummary &s) const
1466 {
1467   return summary_node(tbl(), node, s);
1468 }
1469
1470 bool CircleNodeSummaryBuilder::summary(const luci::CircleRank *node, locop::NodeSummary &s) const
1471 {
1472   return use_input(tbl(), node, s);
1473 }
1474
1475 bool CircleNodeSummaryBuilder::summary(const luci::CircleReduceAny *node,
1476                                        locop::NodeSummary &s) const
1477 {
1478   return use_reducer(tbl(), node, s);
1479 }
1480
1481 bool CircleNodeSummaryBuilder::summary(const luci::CircleReduceMax *node,
1482                                        locop::NodeSummary &s) const
1483 {
1484   return use_reducer(tbl(), node, s);
1485 }
1486
1487 bool CircleNodeSummaryBuilder::summary(const luci::CircleReduceMin *node,
1488                                        locop::NodeSummary &s) const
1489 {
1490   return use_reducer(tbl(), node, s);
1491 }
1492
1493 bool CircleNodeSummaryBuilder::summary(const luci::CircleReduceProd *node,
1494                                        locop::NodeSummary &s) const
1495 {
1496   return use_reducer(tbl(), node, s);
1497 }
1498
1499 bool CircleNodeSummaryBuilder::summary(const luci::CircleRelu *node, locop::NodeSummary &s) const
1500 {
1501   return use_features(tbl(), node, s);
1502 }
1503
1504 bool CircleNodeSummaryBuilder::summary(const luci::CircleRelu6 *node, locop::NodeSummary &s) const
1505 {
1506   return use_features(tbl(), node, s);
1507 }
1508
1509 bool CircleNodeSummaryBuilder::summary(const luci::CircleReluN1To1 *node,
1510                                        locop::NodeSummary &s) const
1511 {
1512   return use_features(tbl(), node, s);
1513 }
1514
1515 bool CircleNodeSummaryBuilder::summary(const luci::CircleReshape *node, locop::NodeSummary &s) const
1516 {
1517   return summary_node(tbl(), node, s);
1518 }
1519
1520 bool CircleNodeSummaryBuilder::summary(const luci::CircleResizeBilinear *node,
1521                                        locop::NodeSummary &s) const
1522 {
1523   return summary_node(tbl(), node, s);
1524 }
1525
1526 bool CircleNodeSummaryBuilder::summary(const luci::CircleResizeNearestNeighbor *node,
1527                                        locop::NodeSummary &s) const
1528 {
1529   return summary_node(tbl(), node, s);
1530 }
1531
1532 bool CircleNodeSummaryBuilder::summary(const luci::CircleReverseSequence *node,
1533                                        locop::NodeSummary &s) const
1534 {
1535   return summary_node(tbl(), node, s);
1536 }
1537
1538 bool CircleNodeSummaryBuilder::summary(const luci::CircleReverseV2 *node,
1539                                        locop::NodeSummary &s) const
1540 {
1541   return summary_node(tbl(), node, s);
1542 }
1543
1544 bool CircleNodeSummaryBuilder::summary(const luci::CircleRound *node, locop::NodeSummary &s) const
1545 {
1546   return use_x(tbl(), node, s);
1547 }
1548
1549 bool CircleNodeSummaryBuilder::summary(const luci::CircleRsqrt *node, locop::NodeSummary &s) const
1550 {
1551   return use_x(tbl(), node, s);
1552 }
1553
1554 bool CircleNodeSummaryBuilder::summary(const luci::CircleScatterNd *node,
1555                                        locop::NodeSummary &s) const
1556 {
1557   return summary_node(tbl(), node, s);
1558 }
1559
1560 bool CircleNodeSummaryBuilder::summary(const luci::CircleSegmentSum *node,
1561                                        locop::NodeSummary &s) const
1562 {
1563   return summary_node(tbl(), node, s);
1564 }
1565
1566 bool CircleNodeSummaryBuilder::summary(const luci::CircleSelect *node, locop::NodeSummary &s) const
1567 {
1568   return summary_node(tbl(), node, s);
1569 }
1570
1571 bool CircleNodeSummaryBuilder::summary(const luci::CircleSelectV2 *node,
1572                                        locop::NodeSummary &s) const
1573 {
1574   return summary_node(tbl(), node, s);
1575 }
1576
1577 bool CircleNodeSummaryBuilder::summary(const luci::CircleShape *node, locop::NodeSummary &s) const
1578 {
1579   return summary_node(tbl(), node, s);
1580 }
1581
1582 bool CircleNodeSummaryBuilder::summary(const luci::CircleSin *node, locop::NodeSummary &s) const
1583 {
1584   return use_x(tbl(), node, s);
1585 }
1586
1587 bool CircleNodeSummaryBuilder::summary(const luci::CircleSlice *node, locop::NodeSummary &s) const
1588 {
1589   return summary_node(tbl(), node, s);
1590 }
1591
1592 bool CircleNodeSummaryBuilder::summary(const luci::CircleSoftmax *node, locop::NodeSummary &s) const
1593 {
1594   return summary_node(tbl(), node, s);
1595 }
1596
1597 bool CircleNodeSummaryBuilder::summary(const luci::CircleSpaceToBatchND *node,
1598                                        locop::NodeSummary &s) const
1599 {
1600   return summary_node(tbl(), node, s);
1601 }
1602
1603 bool CircleNodeSummaryBuilder::summary(const luci::CircleSpaceToDepth *node,
1604                                        locop::NodeSummary &s) const
1605 {
1606   return summary_node(tbl(), node, s);
1607 }
1608
1609 bool CircleNodeSummaryBuilder::summary(const luci::CircleSparseToDense *node,
1610                                        locop::NodeSummary &s) const
1611 {
1612   return summary_node(tbl(), node, s);
1613 }
1614
1615 bool CircleNodeSummaryBuilder::summary(const luci::CircleSplit *node, locop::NodeSummary &s) const
1616 {
1617   return summary_node(tbl(), node, s);
1618 }
1619
1620 bool CircleNodeSummaryBuilder::summary(const luci::CircleSplitV *node, locop::NodeSummary &s) const
1621 {
1622   return summary_node(tbl(), node, s);
1623 }
1624
1625 bool CircleNodeSummaryBuilder::summary(const luci::CircleSqrt *node, locop::NodeSummary &s) const
1626 {
1627   return use_x(tbl(), node, s);
1628 }
1629
1630 bool CircleNodeSummaryBuilder::summary(const luci::CircleSquare *node, locop::NodeSummary &s) const
1631 {
1632   return use_x(tbl(), node, s);
1633 }
1634
1635 bool CircleNodeSummaryBuilder::summary(const luci::CircleSquaredDifference *node,
1636                                        locop::NodeSummary &s) const
1637 {
1638   return use_xy(tbl(), node, s);
1639 }
1640
1641 bool CircleNodeSummaryBuilder::summary(const luci::CircleSqueeze *node, locop::NodeSummary &s) const
1642 {
1643   return summary_node(tbl(), node, s);
1644 }
1645
1646 bool CircleNodeSummaryBuilder::summary(const luci::CircleStridedSlice *node,
1647                                        locop::NodeSummary &s) const
1648 {
1649   return summary_node(tbl(), node, s);
1650 }
1651
1652 bool CircleNodeSummaryBuilder::summary(const luci::CircleSub *node, locop::NodeSummary &s) const
1653 {
1654   return use_xy(tbl(), node, s);
1655 }
1656
1657 bool CircleNodeSummaryBuilder::summary(const luci::CircleSum *node, locop::NodeSummary &s) const
1658 {
1659   return use_reducer(tbl(), node, s);
1660 }
1661
1662 bool CircleNodeSummaryBuilder::summary(const luci::CircleTanh *node, locop::NodeSummary &s) const
1663 {
1664   return use_x(tbl(), node, s);
1665 }
1666
1667 bool CircleNodeSummaryBuilder::summary(const luci::CircleTile *node, locop::NodeSummary &s) const
1668 {
1669   return summary_node(tbl(), node, s);
1670 }
1671
1672 bool CircleNodeSummaryBuilder::summary(const luci::CircleTopKV2 *node, locop::NodeSummary &s) const
1673 {
1674   return summary_node(tbl(), node, s);
1675 }
1676
1677 bool CircleNodeSummaryBuilder::summary(const luci::CircleTranspose *node,
1678                                        locop::NodeSummary &s) const
1679 {
1680   return summary_node(tbl(), node, s);
1681 }
1682
1683 bool CircleNodeSummaryBuilder::summary(const luci::CircleTransposeConv *node,
1684                                        locop::NodeSummary &s) const
1685 {
1686   return summary_node(tbl(), node, s);
1687 }
1688
1689 bool CircleNodeSummaryBuilder::summary(const luci::CircleUnique *node, locop::NodeSummary &s) const
1690 {
1691   return summary_node(tbl(), node, s);
1692 }
1693
1694 bool CircleNodeSummaryBuilder::summary(const luci::CircleUnpack *node, locop::NodeSummary &s) const
1695 {
1696   return summary_node(tbl(), node, s);
1697 }
1698
1699 bool CircleNodeSummaryBuilder::summary(const luci::CircleWhere *node, locop::NodeSummary &s) const
1700 {
1701   return summary_node(tbl(), node, s);
1702 }
1703
1704 bool CircleNodeSummaryBuilder::summary(const luci::CircleWhile *node, locop::NodeSummary &s) const
1705 {
1706   return summary_node(tbl(), node, s);
1707 }
1708
1709 bool CircleNodeSummaryBuilder::summary(const luci::CircleZerosLike *node,
1710                                        locop::NodeSummary &s) const
1711 {
1712   return use_input(tbl(), node, s);
1713 }
1714
1715 bool CircleNodeSummaryBuilder::summary(const luci::CircleSplitOut *node,
1716                                        locop::NodeSummary &s) const
1717 {
1718   return use_input(tbl(), node, s);
1719 }
1720
1721 bool CircleNodeSummaryBuilder::summary(const luci::CircleSplitVOut *node,
1722                                        locop::NodeSummary &s) const
1723 {
1724   return use_input(tbl(), node, s);
1725 }
1726
1727 bool CircleNodeSummaryBuilder::summary(const luci::CircleTopKV2Out *node,
1728                                        locop::NodeSummary &s) const
1729 {
1730   return summary_node(tbl(), node, s);
1731 }
1732
1733 bool CircleNodeSummaryBuilder::summary(const luci::CircleUniqueOut *node,
1734                                        locop::NodeSummary &s) const
1735 {
1736   return summary_node(tbl(), node, s);
1737 }
1738
1739 bool CircleNodeSummaryBuilder::summary(const luci::CircleUnpackOut *node,
1740                                        locop::NodeSummary &s) const
1741 {
1742   return summary_node(tbl(), node, s);
1743 }
1744
1745 bool CircleNodeSummaryBuilder::summary(const luci::CircleIfOut *node, locop::NodeSummary &s) const
1746 {
1747   return use_input(tbl(), node, s);
1748 }
1749
1750 bool CircleNodeSummaryBuilder::summary(const luci::CircleNonMaxSuppressionV4Out *node,
1751                                        locop::NodeSummary &s) const
1752 {
1753   return use_input(tbl(), node, s);
1754 }
1755
1756 bool CircleNodeSummaryBuilder::summary(const luci::CircleNonMaxSuppressionV5Out *node,
1757                                        locop::NodeSummary &s) const
1758 {
1759   return use_input(tbl(), node, s);
1760 }
1761
1762 bool CircleNodeSummaryBuilder::summary(const luci::CircleWhileOut *node,
1763                                        locop::NodeSummary &s) const
1764 {
1765   return summary_node(tbl(), node, s);
1766 }
1767
1768 bool CircleNodeSummaryBuilder::summary(const luci::CircleInput *, locop::NodeSummary &s) const
1769 {
1770   s.state(locop::NodeSummary::State::Complete);
1771   return true;
1772 }
1773
1774 bool CircleNodeSummaryBuilder::summary(const luci::CircleOutput *node, locop::NodeSummary &s) const
1775 {
1776   return summary_node(tbl(), node, s);
1777 }
1778
1779 bool CircleNodeSummaryBuilder::summary(const luci::CircleBCQFullyConnected *node,
1780                                        locop::NodeSummary &s) const
1781 {
1782   return summary_node(tbl(), node, s);
1783 }
1784
1785 bool CircleNodeSummaryBuilder::summary(const luci::CircleBCQGather *node,
1786                                        locop::NodeSummary &s) const
1787 {
1788   return summary_node(tbl(), node, s);
1789 }
1790
1791 bool CircleNodeSummaryBuilder::summary(const luci::CircleInstanceNorm *node,
1792                                        locop::NodeSummary &s) const
1793 {
1794   return summary_node(tbl(), node, s);
1795 }
1796
1797 } // namespace
1798
1799 namespace luci
1800 {
1801
1802 bool NodeSummaryBuilder::build(const loco::Node *node, locop::NodeSummary &s) const
1803 {
1804   if (locop::CanonicalNodeSummaryBuilder(_tbl).build(node, s))
1805   {
1806     return true;
1807   }
1808
1809   if (CircleNodeSummaryBuilder(_tbl).build(node, s))
1810   {
1811     return true;
1812   }
1813
1814   return false;
1815 }
1816
1817 } // namespace luci