2 * Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "CircleNodeSummaryBuilders.h"
19 #include <luci/IR/CircleNode.h>
20 #include <luci/IR/CircleNodes.h>
21 #include <loco/IR/Node.h>
29 std::string to_str(loco::DataType type)
33 case loco::DataType::U8:
35 case loco::DataType::U16:
37 case loco::DataType::U32:
39 case loco::DataType::U64:
42 case loco::DataType::S8:
44 case loco::DataType::S16:
46 case loco::DataType::S32:
48 case loco::DataType::S64:
51 case loco::DataType::FLOAT16:
53 case loco::DataType::FLOAT32:
55 case loco::DataType::FLOAT64:
58 case loco::DataType::BOOL:
66 std::string to_str(float value) { return std::to_string(value); }
68 std::string to_str(int32_t value) { return std::to_string(value); }
70 std::string to_str(bool value) { return value ? "true" : "false"; }
72 std::string to_str(luci::FusedActFunc fused)
76 case luci::FusedActFunc::NONE:
78 case luci::FusedActFunc::RELU:
80 case luci::FusedActFunc::RELU_N1_TO_1:
81 return "RELU_N1_TO_1";
82 case luci::FusedActFunc::RELU6:
84 case luci::FusedActFunc::TANH:
86 case luci::FusedActFunc::SIGN_BIT:
93 std::string to_str(luci::Padding padding)
97 case luci::Padding::SAME:
99 case luci::Padding::VALID:
106 std::string to_str(const luci::Stride *stride)
108 return std::to_string(stride->h()) + "," + std::to_string(stride->w());
111 std::string to_str(const luci::Filter *filter)
113 return std::to_string(filter->h()) + "," + std::to_string(filter->w());
116 std::string to_str(luci::MirrorPadMode mode)
120 case luci::MirrorPadMode::REFLECT:
122 case luci::MirrorPadMode::SYMMETRIC:
134 std::vector<std::string> CircleNodeWithXSummaryBuilder::get_input_names(const luci::CircleNode *)
139 std::vector<std::string>
140 CircleNodeWithINPUTSummaryBuilder::get_input_names(const luci::CircleNode *)
145 std::vector<std::string> CircleNodeWithXYSummaryBuilder::get_input_names(const luci::CircleNode *)
150 std::vector<std::string>
151 CircleNodeWithFEATURESSummaryBuilder::get_input_names(const luci::CircleNode *)
161 bool CircleAddSummaryBuilder::validate(const luci::CircleNode *node)
163 auto add = loco::must_cast<const luci::CircleAdd *>(node);
164 if (add->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED)
170 void CircleAddSummaryBuilder::build_attributes(const luci::CircleNode *node, locop::NodeSummary &s)
172 auto add = loco::must_cast<const luci::CircleAdd *>(node);
173 s.args().append("fused_activation_function", to_str(add->fusedActivationFunction()));
176 std::vector<std::string> CircleAddNSummaryBuilder::get_input_names(const luci::CircleNode *node)
178 return std::vector<std::string>(node->arity(), "inputs");
181 std::vector<std::string> CircleArgMaxSummaryBuilder::get_input_names(const luci::CircleNode *)
183 return {"input", "dimension"};
186 void CircleArgMaxSummaryBuilder::build_attributes(const luci::CircleNode *node,
187 locop::NodeSummary &s)
189 auto argmax = loco::must_cast<const luci::CircleArgMax *>(node);
190 s.args().append("output_type", to_str(argmax->output_type()));
193 std::vector<std::string> CircleArgMinSummaryBuilder::get_input_names(const luci::CircleNode *)
195 return {"input", "dimension"};
198 void CircleArgMinSummaryBuilder::build_attributes(const luci::CircleNode *node,
199 locop::NodeSummary &s)
201 auto argmin = loco::must_cast<const luci::CircleArgMin *>(node);
202 s.args().append("output_type", to_str(argmin->output_type()));
205 bool CircleAveragePool2DSummaryBuilder::validate(const luci::CircleNode *node)
207 auto avgpool = loco::must_cast<const luci::CircleAveragePool2D *>(node);
208 if (avgpool->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED)
210 if (avgpool->padding() == luci::Padding::UNDEFINED)
216 std::vector<std::string>
217 CircleAveragePool2DSummaryBuilder::get_input_names(const luci::CircleNode *)
222 void CircleAveragePool2DSummaryBuilder::build_attributes(const luci::CircleNode *node,
223 locop::NodeSummary &s)
225 auto avgpool = loco::must_cast<const luci::CircleAveragePool2D *>(node);
226 s.args().append("filter(h,w)", to_str(avgpool->filter()));
227 s.args().append("stride(h,w)", to_str(avgpool->stride()));
228 s.args().append("padding", to_str(avgpool->padding()));
229 s.args().append("fused_activation_function", to_str(avgpool->fusedActivationFunction()));
232 void CircleBatchMatMulSummaryBuilder::build_attributes(const luci::CircleNode *node,
233 locop::NodeSummary &s)
235 auto batchmatmul = loco::must_cast<const luci::CircleBatchMatMul *>(node);
236 s.args().append("adj_x", to_str(batchmatmul->adj_x()));
237 s.args().append("adj_y", to_str(batchmatmul->adj_y()));
240 std::vector<std::string>
241 CircleBatchToSpaceNDSummaryBuilder::get_input_names(const luci::CircleNode *)
243 return {"input", "block_shape", "crops"};
246 bool CircleBCQFullyConnectedSummaryBuilder::validate(const luci::CircleNode *node)
248 auto bcq_fc = loco::must_cast<const luci::CircleBCQFullyConnected *>(node);
249 if (bcq_fc->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED)
255 std::vector<std::string>
256 CircleBCQFullyConnectedSummaryBuilder::get_input_names(const luci::CircleNode *)
258 return {"input", "weights_scales", "weights_binary", "bias", "weights_clusters"};
261 void CircleBCQFullyConnectedSummaryBuilder::build_attributes(const luci::CircleNode *node,
262 locop::NodeSummary &s)
264 auto bcq_fc = loco::must_cast<const luci::CircleBCQFullyConnected *>(node);
265 s.args().append("fused_activation_function", to_str(bcq_fc->fusedActivationFunction()));
266 s.args().append("weights_hidden_size", std::to_string(bcq_fc->weights_hidden_size()));
269 std::vector<std::string> CircleBCQGatherSummaryBuilder::get_input_names(const luci::CircleNode *)
271 return {"input_scales", "input_binary", "indices", "input_clusters"};
274 void CircleBCQGatherSummaryBuilder::build_attributes(const luci::CircleNode *node,
275 locop::NodeSummary &s)
277 auto bcq_gather = loco::must_cast<const luci::CircleBCQGather *>(node);
278 s.args().append("axis", std::to_string(bcq_gather->axis()));
279 s.args().append("input_hidden_size", std::to_string(bcq_gather->input_hidden_size()));
282 std::vector<std::string>
283 CircleBidirectionalSequenceLSTMSummaryBuilder::get_input_names(const luci::CircleNode *)
286 "fw_input_to_input_weights",
287 "fw_input_to_forget_weights",
288 "fw_input_to_cell_weights",
289 "fw_input_to_output_weights",
290 "fw_recurrent_to_input_weights",
291 "fw_recurrent_to_forget_weights",
292 "fw_recurrent_to_cell_weights",
293 "fw_recurrent_to_output_weights",
294 "fw_cell_to_input_weights",
295 "fw_cell_to_forget_weights",
296 "fw_cell_to_output_weights",
297 "fw_input_gate_bias",
298 "fw_forget_gate_bias",
300 "fw_output_gate_bias",
301 "fw_projection_weights",
302 "fw_projection_bias",
303 "bw_input_to_input_weights",
304 "bw_input_to_forget_weights",
305 "bw_input_to_cell_weights",
306 "bw_input_to_output_weights",
307 "bw_recurrent_to_input_weights",
308 "bw_recurrent_to_forget_weights",
309 "bw_recurrent_to_cell_weights",
310 "bw_recurrent_to_output_weights",
311 "bw_cell_to_input_weights",
312 "bw_cell_to_forget_weights",
313 "bw_cell_to_output_weights",
314 "bw_input_gate_bias",
315 "bw_forget_gate_bias",
317 "bw_output_gate_bias",
318 "bw_projection_weights",
319 "bw_projection_bias",
320 "fw_activation_state",
322 "bw_activation_state",
325 "fw_auxillary_input_to_input_weights",
326 "fw_auxillary_input_to_forget_weights",
327 "fw_auxillary_input_to_cell_weights",
328 "fw_auxillary_input_to_output_weights",
329 "bw_auxillary_input_to_input_weights",
330 "bw_auxillary_input_to_forget_weights",
331 "bw_auxillary_input_to_cell_weights",
332 "bw_auxillary_input_to_output_weights"};
335 void CircleBidirectionalSequenceLSTMSummaryBuilder::build_attributes(const luci::CircleNode *node,
336 locop::NodeSummary &s)
338 auto lstm = loco::must_cast<const luci::CircleBidirectionalSequenceLSTM *>(node);
339 s.args().append("cell_clip", to_str(lstm->cell_clip()));
340 s.args().append("proj_clip", to_str(lstm->proj_clip()));
341 s.args().append("merge_outputs", to_str(lstm->merge_outputs()));
342 s.args().append("time_major", to_str(lstm->time_major()));
343 s.args().append("asymmetric_quantize_inputs", to_str(lstm->asymmetric_quantize_inputs()));
346 std::vector<std::string> CircleCastSummaryBuilder::get_input_names(const luci::CircleNode *)
351 void CircleCastSummaryBuilder::build_attributes(const luci::CircleNode *node, locop::NodeSummary &s)
353 auto cast = loco::must_cast<const luci::CircleCast *>(node);
354 s.args().append("in_data_type", to_str(cast->in_data_type()));
355 s.args().append("out_data_type", to_str(cast->out_data_type()));
358 bool CircleConcatenationSummaryBuilder::validate(const luci::CircleNode *node)
360 auto concat = loco::must_cast<const luci::CircleConcatenation *>(node);
361 if (concat->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED)
367 std::vector<std::string>
368 CircleConcatenationSummaryBuilder::get_input_names(const luci::CircleNode *node)
370 return std::vector<std::string>(node->arity(), "values");
373 void CircleConcatenationSummaryBuilder::build_attributes(const luci::CircleNode *node,
374 locop::NodeSummary &s)
376 auto concat = loco::must_cast<const luci::CircleConcatenation *>(node);
377 s.args().append("axis", std::to_string(concat->axis()));
378 s.args().append("fused_activation_function", to_str(concat->fusedActivationFunction()));
381 void CircleConstSummaryBuilder::build_attributes(const luci::CircleNode *node,
382 locop::NodeSummary &s)
384 auto circonst = loco::must_cast<const luci::CircleConst *>(node);
385 s.args().append("dtype", to_str(circonst->dtype()));
386 s.args().append("rank", std::to_string(circonst->rank()));
388 for (uint32_t r = 0; r < circonst->rank(); ++r)
392 shape += std::to_string(circonst->dim(r).value());
394 s.args().append("shape", "[" + shape + "]");
397 void CircleConstSummaryBuilder::update_status(locop::NodeSummary &s)
399 s.state(locop::NodeDesc::State::PartiallyKnown);
402 bool CircleConv2DSummaryBuilder::validate(const luci::CircleNode *node)
404 auto conv2d = loco::must_cast<const luci::CircleConv2D *>(node);
405 if (conv2d->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED)
407 if (conv2d->padding() == luci::Padding::UNDEFINED)
413 std::vector<std::string> CircleConv2DSummaryBuilder::get_input_names(const luci::CircleNode *)
415 return {"input", "filter", "bias"};
418 void CircleConv2DSummaryBuilder::build_attributes(const luci::CircleNode *node,
419 locop::NodeSummary &s)
421 auto conv2d = loco::must_cast<const luci::CircleConv2D *>(node);
422 s.args().append("stride(h,w)", to_str(conv2d->stride()));
423 s.args().append("dilation(h,w)", to_str(conv2d->dilation()));
424 s.args().append("padding", to_str(conv2d->padding()));
425 s.args().append("fused_activation_function", to_str(conv2d->fusedActivationFunction()));
428 std::vector<std::string> CircleCustomSummaryBuilder::get_input_names(const luci::CircleNode *node)
430 auto input_names = std::vector<std::string>();
431 for (uint32_t i = 0; i < node->arity(); ++i)
432 input_names.push_back("input" + std::to_string(i));
436 void CircleCustomSummaryBuilder::build_attributes(const luci::CircleNode *node,
437 locop::NodeSummary &s)
439 auto custom = loco::must_cast<const luci::CircleCustom *>(node);
440 s.args().append("custom_code", custom->custom_code());
443 void CircleDepthToSpaceSummaryBuilder::build_attributes(const luci::CircleNode *node,
444 locop::NodeSummary &s)
446 auto depth_to_space = loco::must_cast<const luci::CircleDepthToSpace *>(node);
447 s.args().append("block_size", std::to_string(depth_to_space->block_size()));
450 bool CircleDepthwiseConv2DSummaryBuilder::validate(const luci::CircleNode *node)
452 auto dw_conv2d = loco::must_cast<const luci::CircleDepthwiseConv2D *>(node);
453 if (dw_conv2d->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED)
455 if (dw_conv2d->padding() == luci::Padding::UNDEFINED)
461 std::vector<std::string>
462 CircleDepthwiseConv2DSummaryBuilder::get_input_names(const luci::CircleNode *)
464 return {"input", "filter", "bias"};
467 void CircleDepthwiseConv2DSummaryBuilder::build_attributes(const luci::CircleNode *node,
468 locop::NodeSummary &s)
470 auto dw_conv2d = loco::must_cast<const luci::CircleDepthwiseConv2D *>(node);
471 s.args().append("stride(h,w)", to_str(dw_conv2d->stride()));
472 s.args().append("dilation(h,w)", to_str(dw_conv2d->dilation()));
473 s.args().append("padding", to_str(dw_conv2d->padding()));
474 s.args().append("depthMultiplier", std::to_string(dw_conv2d->depthMultiplier()));
475 s.args().append("fused_activation_function", to_str(dw_conv2d->fusedActivationFunction()));
478 std::vector<std::string> CircleExpandDimsSummaryBuilder::get_input_names(const luci::CircleNode *)
480 return {"input", "axis"};
483 std::vector<std::string> CircleFakeQuantSummaryBuilder::get_input_names(const luci::CircleNode *)
488 void CircleFakeQuantSummaryBuilder::build_attributes(const luci::CircleNode *node,
489 locop::NodeSummary &s)
491 auto fake_quant = loco::must_cast<const luci::CircleFakeQuant *>(node);
492 s.args().append("min", std::to_string(fake_quant->min()));
493 s.args().append("max", std::to_string(fake_quant->max()));
494 s.args().append("num_bits", std::to_string(fake_quant->num_bits()));
495 s.args().append("narrow_range", to_str(fake_quant->narrow_range()));
498 std::vector<std::string> CircleFillSummaryBuilder::get_input_names(const luci::CircleNode *)
500 return {"dims", "value"};
503 bool CircleFullyConnectedSummaryBuilder::validate(const luci::CircleNode *node)
505 auto fc = loco::must_cast<const luci::CircleFullyConnected *>(node);
506 if (fc->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED)
512 std::vector<std::string>
513 CircleFullyConnectedSummaryBuilder::get_input_names(const luci::CircleNode *)
515 return {"input", "weights", "bias"};
518 void CircleFullyConnectedSummaryBuilder::build_attributes(const luci::CircleNode *node,
519 locop::NodeSummary &s)
521 auto fc = loco::must_cast<const luci::CircleFullyConnected *>(node);
522 s.args().append("fused_activation_function", to_str(fc->fusedActivationFunction()));
525 std::vector<std::string> CircleGatherSummaryBuilder::get_input_names(const luci::CircleNode *)
527 return {"params", "indices"};
530 void CircleGatherSummaryBuilder::build_attributes(const luci::CircleNode *node,
531 locop::NodeSummary &s)
533 auto gather = loco::must_cast<const luci::CircleGather *>(node);
534 s.args().append("axis", std::to_string(gather->axis()));
537 std::vector<std::string> CircleGatherNdSummaryBuilder::get_input_names(const luci::CircleNode *)
539 return {"params", "indices"};
542 std::vector<std::string> CircleIfSummaryBuilder::get_input_names(const luci::CircleNode *node)
544 auto circle_if = loco::must_cast<const luci::CircleIf *>(node);
546 auto input_names = std::vector<std::string>();
547 input_names.push_back("cond");
548 for (uint32_t i = 0; i < circle_if->input_count(); ++i)
549 input_names.push_back("input");
554 void CircleIfSummaryBuilder::build_attributes(const luci::CircleNode *node, locop::NodeSummary &s)
556 auto circle_if = loco::must_cast<const luci::CircleIf *>(node);
558 if (circle_if->then_graph() != nullptr)
559 s.args().append("then_graph", circle_if->then_graph()->name());
561 s.args().append("then_branch", std::to_string(circle_if->then_branch()));
563 if (circle_if->else_graph() != nullptr)
564 s.args().append("else_graph", circle_if->else_graph()->name());
566 s.args().append("else_branch", std::to_string(circle_if->else_branch()));
569 bool CircleInstanceNormSummaryBuilder::validate(const luci::CircleNode *node)
571 auto instnorm = loco::must_cast<const luci::CircleInstanceNorm *>(node);
572 if (instnorm->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED)
578 std::vector<std::string> CircleInstanceNormSummaryBuilder::get_input_names(const luci::CircleNode *)
580 return {"input", "gamma", "beta"};
583 void CircleInstanceNormSummaryBuilder::build_attributes(const luci::CircleNode *node,
584 locop::NodeSummary &s)
586 auto instnorm = loco::must_cast<const luci::CircleInstanceNorm *>(node);
587 s.args().append("epsilon", std::to_string(instnorm->epsilon()));
588 s.args().append("fused_activation_function", to_str(instnorm->fusedActivationFunction()));
591 bool CircleL2NormalizeSummaryBuilder::validate(const luci::CircleNode *node)
593 auto l2norm = loco::must_cast<const luci::CircleL2Normalize *>(node);
594 if (l2norm->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED)
600 std::vector<std::string> CircleL2NormalizeSummaryBuilder::get_input_names(const luci::CircleNode *)
605 void CircleL2NormalizeSummaryBuilder::build_attributes(const luci::CircleNode *node,
606 locop::NodeSummary &s)
608 auto l2norm = loco::must_cast<const luci::CircleL2Normalize *>(node);
609 s.args().append("fused_activation_function", to_str(l2norm->fusedActivationFunction()));
612 bool CircleL2Pool2DSummaryBuilder::validate(const luci::CircleNode *node)
614 auto l2pool = loco::must_cast<const luci::CircleL2Pool2D *>(node);
615 if (l2pool->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED)
617 if (l2pool->padding() == luci::Padding::UNDEFINED)
623 std::vector<std::string> CircleL2Pool2DSummaryBuilder::get_input_names(const luci::CircleNode *)
628 void CircleL2Pool2DSummaryBuilder::build_attributes(const luci::CircleNode *node,
629 locop::NodeSummary &s)
631 auto l2pool = loco::must_cast<const luci::CircleL2Pool2D *>(node);
632 s.args().append("filter(h,w)", to_str(l2pool->filter()));
633 s.args().append("stride(h,w)", to_str(l2pool->stride()));
634 s.args().append("padding", to_str(l2pool->padding()));
635 s.args().append("fused_activation_function", to_str(l2pool->fusedActivationFunction()));
638 void CircleLeakyReluSummaryBuilder::build_attributes(const luci::CircleNode *node,
639 locop::NodeSummary &s)
641 auto leaky_relu = loco::must_cast<const luci::CircleLeakyRelu *>(node);
642 s.args().append("alpha", std::to_string(leaky_relu->alpha()));
645 void CircleLocalResponseNormalizationSummaryBuilder::build_attributes(const luci::CircleNode *node,
646 locop::NodeSummary &s)
648 auto lrn = loco::must_cast<const luci::CircleLocalResponseNormalization *>(node);
649 s.args().append("radius", std::to_string(lrn->radius()));
650 s.args().append("bias", std::to_string(lrn->bias()));
651 s.args().append("alpha", std::to_string(lrn->alpha()));
652 s.args().append("beta", std::to_string(lrn->beta()));
655 std::vector<std::string> CircleLogSoftmaxSummaryBuilder::get_input_names(const luci::CircleNode *)
660 std::vector<std::string> CircleMatrixDiagSummaryBuilder::get_input_names(const luci::CircleNode *)
665 std::vector<std::string>
666 CircleMatrixSetDiagSummaryBuilder::get_input_names(const luci::CircleNode *)
668 return {"input", "diagonal"};
671 bool CircleMaxPool2DSummaryBuilder::validate(const luci::CircleNode *node)
673 auto maxpool = loco::must_cast<const luci::CircleMaxPool2D *>(node);
674 if (maxpool->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED)
676 if (maxpool->padding() == luci::Padding::UNDEFINED)
682 std::vector<std::string> CircleMaxPool2DSummaryBuilder::get_input_names(const luci::CircleNode *)
687 void CircleMaxPool2DSummaryBuilder::build_attributes(const luci::CircleNode *node,
688 locop::NodeSummary &s)
690 auto maxpool = loco::must_cast<const luci::CircleMaxPool2D *>(node);
691 s.args().append("filter(h,w)", to_str(maxpool->filter()));
692 s.args().append("stride(h,w)", to_str(maxpool->stride()));
693 s.args().append("padding", to_str(maxpool->padding()));
694 s.args().append("fused_activation_function", to_str(maxpool->fusedActivationFunction()));
697 bool CircleMirrorPadSummaryBuilder::validate(const luci::CircleNode *node)
699 auto mirror_pad = loco::must_cast<const luci::CircleMirrorPad *>(node);
700 if (mirror_pad->mode() == luci::MirrorPadMode::UNDEFINED)
706 std::vector<std::string> CircleMirrorPadSummaryBuilder::get_input_names(const luci::CircleNode *)
708 return {"input", "paddings"};
711 void CircleMirrorPadSummaryBuilder::build_attributes(const luci::CircleNode *node,
712 locop::NodeSummary &s)
714 auto mirror_pad = loco::must_cast<const luci::CircleMirrorPad *>(node);
715 s.args().append("mode", to_str(mirror_pad->mode()));
718 bool CircleMulSummaryBuilder::validate(const luci::CircleNode *node)
720 auto mul = loco::must_cast<const luci::CircleMul *>(node);
721 if (mul->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED)
727 void CircleMulSummaryBuilder::build_attributes(const luci::CircleNode *node, locop::NodeSummary &s)
729 auto mul = loco::must_cast<const luci::CircleMul *>(node);
730 s.args().append("fused_activation_function", to_str(mul->fusedActivationFunction()));
733 std::vector<std::string>
734 CircleNonMaxSuppressionV4SummaryBuilder::get_input_names(const luci::CircleNode *)
736 return {"boxes", "scores", "max_output_size", "iou_threshold", "score_threshold"};
739 std::vector<std::string>
740 CircleNonMaxSuppressionV5SummaryBuilder::get_input_names(const luci::CircleNode *)
742 return {"boxes", "scores", "max_output_size",
743 "iou_threshold", "score_threshold", "soft_nms_sigma"};
746 std::vector<std::string> CircleOneHotSummaryBuilder::get_input_names(const luci::CircleNode *)
748 return {"indices", "depth", "on_value", "off_value"};
751 void CircleOneHotSummaryBuilder::build_attributes(const luci::CircleNode *node,
752 locop::NodeSummary &s)
754 auto onehot = loco::must_cast<const luci::CircleOneHot *>(node);
755 s.args().append("axis", std::to_string(onehot->axis()));
758 std::vector<std::string> CirclePackSummaryBuilder::get_input_names(const luci::CircleNode *node)
760 return std::vector<std::string>(node->arity(), "values");
763 void CirclePackSummaryBuilder::build_attributes(const luci::CircleNode *node, locop::NodeSummary &s)
765 auto pack = loco::must_cast<const luci::CirclePack *>(node);
766 s.args().append("values_count", std::to_string(pack->values_count()));
767 s.args().append("axis", std::to_string(pack->axis()));
770 std::vector<std::string> CirclePadSummaryBuilder::get_input_names(const luci::CircleNode *)
772 return {"input", "paddings"};
775 std::vector<std::string> CirclePadV2SummaryBuilder::get_input_names(const luci::CircleNode *)
777 return {"input", "paddings", "constant_values"};
780 std::vector<std::string> CirclePReluSummaryBuilder::get_input_names(const luci::CircleNode *)
782 return {"input", "alpha"};
785 std::vector<std::string> CircleRangeSummaryBuilder::get_input_names(const luci::CircleNode *)
787 return {"start", "limit", "delta"};
790 std::vector<std::string> CircleReshapeSummaryBuilder::get_input_names(const luci::CircleNode *)
792 return {"tensor", "shape"};
795 void CircleReshapeSummaryBuilder::update_status(locop::NodeSummary &s)
797 s.state(locop::NodeDesc::State::PartiallyKnown);
800 std::vector<std::string>
801 CircleResizeBilinearSummaryBuilder::get_input_names(const luci::CircleNode *)
803 return {"input", "size"};
806 void CircleResizeBilinearSummaryBuilder::build_attributes(const luci::CircleNode *node,
807 locop::NodeSummary &s)
809 auto resize_bilinear = loco::must_cast<const luci::CircleResizeBilinear *>(node);
810 s.args().append("align_corners", to_str(resize_bilinear->align_corners()));
811 s.args().append("half_pixel_centers", to_str(resize_bilinear->half_pixel_centers()));
814 std::vector<std::string>
815 CircleResizeNearestNeighborSummaryBuilder::get_input_names(const luci::CircleNode *)
817 return {"input", "size"};
820 void CircleResizeNearestNeighborSummaryBuilder::build_attributes(const luci::CircleNode *node,
821 locop::NodeSummary &s)
823 auto resize_nn = loco::must_cast<const luci::CircleResizeNearestNeighbor *>(node);
824 s.args().append("align_corners", to_str(resize_nn->align_corners()));
827 std::vector<std::string>
828 CircleReverseSequenceSummaryBuilder::get_input_names(const luci::CircleNode *)
830 return {"input", "seq_lengths"};
833 void CircleReverseSequenceSummaryBuilder::build_attributes(const luci::CircleNode *node,
834 locop::NodeSummary &s)
836 auto reverse_seq = loco::must_cast<const luci::CircleReverseSequence *>(node);
837 s.args().append("seq_axis", std::to_string(reverse_seq->seq_axis()));
838 s.args().append("batch_axis", std::to_string(reverse_seq->batch_axis()));
841 std::vector<std::string> CircleReverseV2SummaryBuilder::get_input_names(const luci::CircleNode *)
843 return {"tensor", "axis"};
846 std::vector<std::string> CircleScatterNdSummaryBuilder::get_input_names(const luci::CircleNode *)
848 return {"indices", "updates", "shape"};
851 std::vector<std::string> CircleSegmentSumSummaryBuilder::get_input_names(const luci::CircleNode *)
853 return {"input", "segment_ids"};
856 std::vector<std::string> CircleSelectSummaryBuilder::get_input_names(const luci::CircleNode *)
858 return {"condition", "t", "e"};
861 std::vector<std::string> CircleSelectV2SummaryBuilder::get_input_names(const luci::CircleNode *)
863 return {"condition", "t", "e"};
866 void CircleShapeSummaryBuilder::build_attributes(const luci::CircleNode *node,
867 locop::NodeSummary &s)
869 auto shape = loco::must_cast<const luci::CircleShape *>(node);
870 s.args().append("out_type", to_str(shape->out_type()));
873 std::vector<std::string> CircleSliceSummaryBuilder::get_input_names(const luci::CircleNode *)
875 return {"input", "begin", "size"};
878 std::vector<std::string> CircleSoftmaxSummaryBuilder::get_input_names(const luci::CircleNode *)
883 void CircleSoftmaxSummaryBuilder::build_attributes(const luci::CircleNode *node,
884 locop::NodeSummary &s)
886 auto softmax = loco::must_cast<const luci::CircleSoftmax *>(node);
887 s.args().append("beta", to_str(softmax->beta()));
890 std::vector<std::string>
891 CircleSpaceToBatchNDSummaryBuilder::get_input_names(const luci::CircleNode *)
893 return {"input", "block_shape", "paddings"};
896 void CircleSpaceToDepthSummaryBuilder::build_attributes(const luci::CircleNode *node,
897 locop::NodeSummary &s)
899 auto space_to_depth = loco::must_cast<const luci::CircleSpaceToDepth *>(node);
900 s.args().append("block_size", to_str(space_to_depth->block_size()));
903 std::vector<std::string>
904 CircleSparseToDenseSummaryBuilder::get_input_names(const luci::CircleNode *)
906 return {"indices", "output_shape", "values", "default_value"};
909 void CircleSparseToDenseSummaryBuilder::build_attributes(const luci::CircleNode *node,
910 locop::NodeSummary &s)
912 auto sparse_to_dense = loco::must_cast<const luci::CircleSparseToDense *>(node);
913 s.args().append("validate_indices", to_str(sparse_to_dense->validate_indices()));
916 std::vector<std::string> CircleSplitSummaryBuilder::get_input_names(const luci::CircleNode *)
918 return {"split_dim", "input"};
921 void CircleSplitSummaryBuilder::build_attributes(const luci::CircleNode *node,
922 locop::NodeSummary &s)
924 auto split = loco::must_cast<const luci::CircleSplit *>(node);
925 s.args().append("num_split", std::to_string(split->num_split()));
928 std::vector<std::string> CircleSplitVSummaryBuilder::get_input_names(const luci::CircleNode *)
930 return {"input", "size_splits", "split_dim"};
933 void CircleSplitVSummaryBuilder::build_attributes(const luci::CircleNode *node,
934 locop::NodeSummary &s)
936 auto split_v = loco::must_cast<const luci::CircleSplitV *>(node);
937 s.args().append("num_split", std::to_string(split_v->num_split()));
940 void CircleSqueezeSummaryBuilder::build_attributes(const luci::CircleNode *node,
941 locop::NodeSummary &s)
943 auto squeeze = loco::must_cast<const luci::CircleSqueeze *>(node);
945 std::string squeeze_dims = "(";
946 for (size_t i = 0; i < squeeze->squeeze_dims().size(); ++i)
949 squeeze_dims += ", ";
950 squeeze_dims += std::to_string(squeeze->squeeze_dims().at(i));
954 s.args().append("squeeze_dims", squeeze_dims);
957 std::vector<std::string> CircleStridedSliceSummaryBuilder::get_input_names(const luci::CircleNode *)
959 return {"input", "begin", "end", "strides"};
962 void CircleStridedSliceSummaryBuilder::build_attributes(const luci::CircleNode *node,
963 locop::NodeSummary &s)
965 auto strided_slice = loco::must_cast<const luci::CircleStridedSlice *>(node);
966 s.args().append("begin_mask", std::to_string(strided_slice->begin_mask()));
967 s.args().append("end_mask", std::to_string(strided_slice->end_mask()));
968 s.args().append("ellipsis_mask", std::to_string(strided_slice->ellipsis_mask()));
969 s.args().append("new_axis_mask", std::to_string(strided_slice->new_axis_mask()));
970 s.args().append("shrink_axis_mask", std::to_string(strided_slice->shrink_axis_mask()));
973 bool CircleSVDFSummaryBuilder::validate(const luci::CircleNode *node)
975 auto svdf = loco::must_cast<const luci::CircleSVDF *>(node);
976 if (svdf->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED)
982 std::vector<std::string> CircleSVDFSummaryBuilder::get_input_names(const luci::CircleNode *)
984 return {"input", "weight_feature", "weight_time", "bias", "State"};
987 void CircleSVDFSummaryBuilder::build_attributes(const luci::CircleNode *node, locop::NodeSummary &s)
989 auto svdf = loco::must_cast<const luci::CircleSVDF *>(node);
990 s.args().append("rank", to_str(svdf->svdf_rank()));
991 s.args().append("asymmetric_quantize_inputs", to_str(svdf->asymmetric_quantize_inputs()));
992 s.args().append("fused_activation_function", to_str(svdf->fusedActivationFunction()));
995 std::vector<std::string> CircleTileSummaryBuilder::get_input_names(const luci::CircleNode *)
997 return {"input", "multiples"};
1000 std::vector<std::string> CircleTopKV2SummaryBuilder::get_input_names(const luci::CircleNode *)
1002 return {"input", "k"};
1005 std::vector<std::string> CircleTransposeSummaryBuilder::get_input_names(const luci::CircleNode *)
1007 return {"a", "perm"};
1010 bool CircleTransposeConvSummaryBuilder::validate(const luci::CircleNode *node)
1012 auto transpose_conv = loco::must_cast<const luci::CircleTransposeConv *>(node);
1013 if (transpose_conv->padding() == luci::Padding::UNDEFINED)
1019 std::vector<std::string>
1020 CircleTransposeConvSummaryBuilder::get_input_names(const luci::CircleNode *)
1022 return {"inputSizes", "filter", "outBackProp", "bias"};
1025 void CircleTransposeConvSummaryBuilder::build_attributes(const luci::CircleNode *node,
1026 locop::NodeSummary &s)
1028 auto transpose_conv = loco::must_cast<const luci::CircleTransposeConv *>(node);
1029 s.args().append("stride(h,w)", to_str(transpose_conv->stride()));
1030 s.args().append("padding", to_str(transpose_conv->padding()));
1033 std::vector<std::string>
1034 CircleUnidirectionalSequenceLSTMSummaryBuilder::get_input_names(const luci::CircleNode *)
1037 "input_to_input_weights",
1038 "input_to_forget_weights",
1039 "input_to_cell_weights",
1040 "input_to_output_weights",
1041 "recurrent_to_input_weights",
1042 "recurrent_to_forget_weights",
1043 "recurrent_to_cell_weights",
1044 "recurrent_to_output_weights",
1045 "cell_to_input_weights",
1046 "cell_to_forget_weights",
1047 "cell_to_output_weights",
1052 "projection_weights",
1056 "input_layer_norm_coefficients",
1057 "forget_layer_norm_coefficients",
1058 "cell_layer_norm_coefficients",
1059 "output_layer_norm_coefficients"};
1062 void CircleUnidirectionalSequenceLSTMSummaryBuilder::build_attributes(const luci::CircleNode *node,
1063 locop::NodeSummary &s)
1065 auto lstm = loco::must_cast<const luci::CircleUnidirectionalSequenceLSTM *>(node);
1066 s.args().append("cell_clip", to_str(lstm->cell_clip()));
1067 s.args().append("proj_clip", to_str(lstm->proj_clip()));
1068 s.args().append("time_major", to_str(lstm->time_major()));
1069 s.args().append("asymmetric_quantize_inputs", to_str(lstm->asymmetric_quantize_inputs()));
1072 void CircleUniqueSummaryBuilder::build_attributes(const luci::CircleNode *node,
1073 locop::NodeSummary &s)
1075 auto unique = loco::must_cast<const luci::CircleUnique *>(node);
1076 s.args().append("idx_out_type", to_str(unique->idx_out_type()));
1079 std::vector<std::string> CircleUnpackSummaryBuilder::get_input_names(const luci::CircleNode *)
1084 void CircleUnpackSummaryBuilder::build_attributes(const luci::CircleNode *node,
1085 locop::NodeSummary &s)
1087 auto unpack = loco::must_cast<const luci::CircleUnpack *>(node);
1088 s.args().append("num", std::to_string(unpack->num()));
1089 s.args().append("axis", std::to_string(unpack->axis()));
1091 std::vector<std::string> CircleWhereSummaryBuilder::get_input_names(const luci::CircleNode *)
1093 return {"condition"};
1096 std::vector<std::string> CircleWhileSummaryBuilder::get_input_names(const luci::CircleNode *node)
1098 auto circle_while = loco::must_cast<const luci::CircleWhile *>(node);
1100 auto input_names = std::vector<std::string>();
1101 for (uint32_t i = 0; i < circle_while->input_count(); ++i)
1102 input_names.push_back("input");
1107 void CircleWhileSummaryBuilder::build_attributes(const luci::CircleNode *node,
1108 locop::NodeSummary &s)
1110 auto circle_while = loco::must_cast<const luci::CircleWhile *>(node);
1112 if (circle_while->cond_graph() != nullptr)
1113 s.args().append("then_graph", circle_while->cond_graph()->name());
1115 s.args().append("then_branch", std::to_string(circle_while->cond_branch()));
1117 if (circle_while->body_graph() != nullptr)
1118 s.args().append("else_graph", circle_while->body_graph()->name());
1120 s.args().append("else_branch", std::to_string(circle_while->body_branch()));
1123 std::vector<std::string> CircleOutputSummaryBuilder::get_input_names(const luci::CircleNode *)
1128 std::vector<std::string> CircleTopKV2OutSummaryBuilder::get_input_names(const luci::CircleNode *)
1133 std::vector<std::string> CircleUniqueOutSummaryBuilder::get_input_names(const luci::CircleNode *)
1138 std::vector<std::string> CircleUnpackOutSummaryBuilder::get_input_names(const luci::CircleNode *)
1143 std::vector<std::string> CircleWhileOutSummaryBuilder::get_input_names(const luci::CircleNode *)