summaryrefslogtreecommitdiff
path: root/compiler/luci
diff options
context:
space:
mode:
authorChunseok Lee <chunseok.lee@samsung.com>2020-08-14 15:19:19 +0900
committerChunseok Lee <chunseok.lee@samsung.com>2020-08-14 15:19:19 +0900
commit042b262b3633b6c0f577aed6cb4b980ad0c1dcf3 (patch)
treee79fb9ffe65b21bdc5863306db2757ab187a3306 /compiler/luci
parent05e0ec30a632339a8533082476f27bda31ccde16 (diff)
downloadnnfw-042b262b3633b6c0f577aed6cb4b980ad0c1dcf3.tar.gz
nnfw-042b262b3633b6c0f577aed6cb4b980ad0c1dcf3.tar.bz2
nnfw-042b262b3633b6c0f577aed6cb4b980ad0c1dcf3.zip
Imported Upstream version 1.8.0upstream/1.8.0submit/tizen/20200814.062151
Diffstat (limited to 'compiler/luci')
-rw-r--r--compiler/luci/export/src/CircleOperationExporter.cpp90
-rw-r--r--compiler/luci/export/src/CircleTensorExporter.cpp5
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes.h2
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleNonMaxSuppressionV4.h35
-rw-r--r--compiler/luci/import/include/luci/Import/Nodes/CircleUnique.h35
-rw-r--r--compiler/luci/import/src/CircleReader.cpp2
-rw-r--r--compiler/luci/import/src/GraphBuilderRegistry.cpp4
-rw-r--r--compiler/luci/import/src/Importer.test.cpp7
-rw-r--r--compiler/luci/import/src/Nodes/CircleAbs.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleAdd.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleArgMax.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleArgMin.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleAveragePool2D.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleBCQFullyConnected.cpp10
-rw-r--r--compiler/luci/import/src/Nodes/CircleBCQGather.cpp8
-rw-r--r--compiler/luci/import/src/Nodes/CircleBatchMatMul.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleBatchToSpaceND.cpp12
-rw-r--r--compiler/luci/import/src/Nodes/CircleCast.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleCeil.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleConv2D.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleCos.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleDepthToSpace.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleDepthwiseConv2D.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleDiv.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleElu.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleEqual.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleExp.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleExpandDims.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleFill.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleFloor.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleFloorDiv.cpp8
-rw-r--r--compiler/luci/import/src/Nodes/CircleFloorMod.cpp8
-rw-r--r--compiler/luci/import/src/Nodes/CircleFullyConnected.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleGather.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleGatherNd.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleGreater.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleGreaterEqual.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleIf.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleInstanceNorm.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleL2Normalize.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleL2Pool2D.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleLeakyRelu.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleLess.cpp8
-rw-r--r--compiler/luci/import/src/Nodes/CircleLessEqual.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleLocalResponseNormalization.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleLog.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleLogSoftmax.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleLogicalAnd.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleLogicalNot.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleLogicalOr.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleLogistic.cpp18
-rw-r--r--compiler/luci/import/src/Nodes/CircleMatrixDiag.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleMatrixSetDiag.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleMaxPool2D.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleMaximum.cpp8
-rw-r--r--compiler/luci/import/src/Nodes/CircleMean.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleMinimum.cpp8
-rw-r--r--compiler/luci/import/src/Nodes/CircleMirrorPad.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleMul.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleNeg.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleNonMaxSuppressionV4.cpp123
-rw-r--r--compiler/luci/import/src/Nodes/CircleNotEqual.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleOneHot.cpp16
-rw-r--r--compiler/luci/import/src/Nodes/CirclePRelu.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CirclePad.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CirclePow.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleRange.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleRank.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleReduceAny.cpp8
-rw-r--r--compiler/luci/import/src/Nodes/CircleReduceMax.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleReduceMin.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleReduceProd.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleRelu.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleRelu6.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleReluN1To1.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleReshape.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleResizeBilinear.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleResizeNearestNeighbor.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleReverseSequence.cpp8
-rw-r--r--compiler/luci/import/src/Nodes/CircleReverseV2.cpp8
-rw-r--r--compiler/luci/import/src/Nodes/CircleRound.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleRsqrt.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleScatterNd.cpp12
-rw-r--r--compiler/luci/import/src/Nodes/CircleSegmentSum.cpp8
-rw-r--r--compiler/luci/import/src/Nodes/CircleSelect.cpp8
-rw-r--r--compiler/luci/import/src/Nodes/CircleSelectV2.cpp12
-rw-r--r--compiler/luci/import/src/Nodes/CircleShape.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleSin.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleSlice.cpp6
-rw-r--r--compiler/luci/import/src/Nodes/CircleSoftmax.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleSpaceToBatchND.cpp12
-rw-r--r--compiler/luci/import/src/Nodes/CircleSpaceToDepth.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleSparseToDense.cpp8
-rw-r--r--compiler/luci/import/src/Nodes/CircleSqrt.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleSquare.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleSquaredDifference.cpp10
-rw-r--r--compiler/luci/import/src/Nodes/CircleSqueeze.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleStridedSlice.cpp8
-rw-r--r--compiler/luci/import/src/Nodes/CircleSub.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleSum.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleTanh.cpp20
-rw-r--r--compiler/luci/import/src/Nodes/CircleTile.cpp10
-rw-r--r--compiler/luci/import/src/Nodes/CircleTopKV2.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleTranspose.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleTransposeConv.cpp24
-rw-r--r--compiler/luci/import/src/Nodes/CircleUnique.cpp89
-rw-r--r--compiler/luci/import/src/Nodes/CircleUnpack.cpp2
-rw-r--r--compiler/luci/import/src/Nodes/CircleWhere.cpp4
-rw-r--r--compiler/luci/import/src/Nodes/CircleZerosLike.cpp2
-rw-r--r--compiler/luci/lang/include/luci/IR/CircleNodes.h5
-rw-r--r--compiler/luci/lang/include/luci/IR/CircleNodes.lst7
-rw-r--r--compiler/luci/lang/include/luci/IR/CircleQuantParam.h1
-rw-r--r--compiler/luci/lang/include/luci/IR/Nodes/CircleConst.h2
-rw-r--r--compiler/luci/lang/include/luci/IR/Nodes/CircleNonMaxSuppressionV4.h53
-rw-r--r--compiler/luci/lang/include/luci/IR/Nodes/CircleNonMaxSuppressionV4Out.h51
-rw-r--r--compiler/luci/lang/include/luci/IR/Nodes/CirclePadV2.h49
-rw-r--r--compiler/luci/lang/include/luci/IR/Nodes/CircleUnique.h47
-rw-r--r--compiler/luci/lang/include/luci/IR/Nodes/CircleUniqueOut.h51
-rw-r--r--compiler/luci/lang/src/Module.test.cpp2
-rw-r--r--compiler/luci/lang/src/Nodes/CircleCustom.test.cpp7
-rw-r--r--compiler/luci/lang/src/Nodes/CircleIf.test.cpp4
-rw-r--r--compiler/luci/lang/src/Nodes/CircleNonMaxSuppressionV4.test.cpp96
-rw-r--r--compiler/luci/lang/src/Nodes/CircleNonMaxSuppressionV4Out.test.cpp32
-rw-r--r--compiler/luci/lang/src/Nodes/CirclePadV2.test.cpp86
-rw-r--r--compiler/luci/lang/src/Nodes/CircleUnique.test.cpp76
-rw-r--r--compiler/luci/lang/src/Nodes/CircleWhile.test.cpp4
-rw-r--r--compiler/luci/logex/src/FormattedGraph.cpp41
-rw-r--r--compiler/luci/pass/src/CircleOptimizer.cpp4
-rw-r--r--compiler/luci/pass/src/FuseBCQPass.cpp435
-rw-r--r--compiler/luci/pass/src/QuantizationUtils.cpp20
-rw-r--r--compiler/luci/pass/src/QuantizeWithMinMaxPass.cpp25
-rw-r--r--compiler/luci/service/src/CircleShapeInferenceRule.cpp59
-rw-r--r--compiler/luci/service/src/CircleTypeInferenceRule.cpp33
-rw-r--r--compiler/luci/tests/test.lst15
134 files changed, 1662 insertions, 481 deletions
diff --git a/compiler/luci/export/src/CircleOperationExporter.cpp b/compiler/luci/export/src/CircleOperationExporter.cpp
index 3c01b676f..bca122050 100644
--- a/compiler/luci/export/src/CircleOperationExporter.cpp
+++ b/compiler/luci/export/src/CircleOperationExporter.cpp
@@ -102,6 +102,7 @@ public:
void visit(luci::CircleMirrorPad *) final;
void visit(luci::CircleMul *) final;
void visit(luci::CircleNeg *) final;
+ void visit(luci::CircleNonMaxSuppressionV4 *) final;
void visit(luci::CircleNotEqual *) final;
void visit(luci::CircleOneHot *) final;
void visit(luci::CirclePack *) final;
@@ -149,6 +150,7 @@ public:
void visit(luci::CircleTopKV2 *) final;
void visit(luci::CircleTranspose *) final;
void visit(luci::CircleTransposeConv *) final;
+ void visit(luci::CircleUnique *) final;
void visit(luci::CircleUnpack *) final;
void visit(luci::CircleWhere *) final;
void visit(luci::CircleWhile *) final;
@@ -165,9 +167,11 @@ public:
// Virtual for multiple-outputs
void visit(luci::CircleCustomOut *) final {}
void visit(luci::CircleIfOut *) final {}
+ void visit(luci::CircleNonMaxSuppressionV4Out *) final {}
void visit(luci::CircleSplitOut *) final {}
void visit(luci::CircleSplitVOut *) final {}
void visit(luci::CircleTopKV2Out *) final {}
+ void visit(luci::CircleUniqueOut *) final {}
void visit(luci::CircleUnpackOut *) final {}
void visit(luci::CircleWhileOut *) final {}
@@ -599,7 +603,9 @@ void OperationExporter::visit(luci::CircleLocalResponseNormalization *node)
{
export_simple(node, circle::BuiltinOperator_LOCAL_RESPONSE_NORMALIZATION,
circle::BuiltinOptions_LocalResponseNormalizationOptions,
- CreateLocalResponseNormalizationOptions(builder).Union());
+ CreateLocalResponseNormalizationOptions(builder, node->radius(), node->bias(),
+ node->alpha(), node->beta())
+ .Union());
}
void OperationExporter::visit(luci::CircleLog *node)
@@ -691,6 +697,49 @@ void OperationExporter::visit(luci::CircleNeg *node)
CreateNegOptions(builder).Union());
}
+void OperationExporter::visit(luci::CircleNonMaxSuppressionV4 *node)
+{
+ auto nms_outs = loco::succs(node);
+ assert(nms_outs.size() == 2);
+
+ uint32_t op_idx =
+ md.registerBuiltinOpcode(circle::BuiltinOperator_NON_MAX_SUPPRESSION_V4, node->op_version());
+ std::vector<int32_t> inputs_vec{
+ get_tensor_index(node->boxes()), get_tensor_index(node->scores()),
+ get_tensor_index(node->max_output_size()), get_tensor_index(node->iou_threshold()),
+ get_tensor_index(node->score_threshold()),
+ };
+ std::vector<int32_t> outputs_vec;
+
+ for (uint32_t idx = 0; idx < nms_outs.size(); ++idx)
+ {
+ // store in order of index
+ bool found = false;
+ for (auto out : nms_outs)
+ {
+ auto nms_out = loco::must_cast<luci::CircleNonMaxSuppressionV4Out *>(out);
+ if (nms_out->index() == static_cast<int32_t>(idx))
+ {
+ outputs_vec.push_back(get_tensor_index(nms_out));
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ {
+ INTERNAL_EXN("Invalid NonMaxSuppressionV4 output");
+ }
+ }
+
+ auto inputs = builder.CreateVector(inputs_vec);
+ auto outputs = builder.CreateVector(outputs_vec);
+ auto options = CreateNonMaxSuppressionV4Options(builder);
+ auto op_offset =
+ CreateOperator(builder, op_idx, inputs, outputs,
+ circle::BuiltinOptions_NonMaxSuppressionV4Options, options.Union());
+ gd._operators.push_back(op_offset);
+}
+
void OperationExporter::visit(luci::CircleNotEqual *node)
{
export_simple(node, circle::BuiltinOperator_NOT_EQUAL, circle::BuiltinOptions_NotEqualOptions,
@@ -890,7 +939,7 @@ void OperationExporter::visit(luci::CircleSpaceToDepth *node)
{
export_simple(node, circle::BuiltinOperator_SPACE_TO_DEPTH,
circle::BuiltinOptions_SpaceToDepthOptions,
- CreateSpaceToDepthOptions(builder).Union());
+ CreateSpaceToDepthOptions(builder, node->block_size()).Union());
}
void OperationExporter::visit(luci::CircleSparseToDense *node)
@@ -1090,6 +1139,43 @@ void OperationExporter::visit(luci::CircleTransposeConv *node)
.Union());
}
+void OperationExporter::visit(luci::CircleUnique *node)
+{
+ auto unique_outs = loco::succs(node);
+ assert(int32_t(unique_outs.size()) == 2);
+ uint32_t op_idx = md.registerBuiltinOpcode(circle::BuiltinOperator_UNIQUE, node->op_version());
+
+ std::vector<int32_t> inputs_vec{get_tensor_index(node->input())};
+ std::vector<int32_t> outputs_vec;
+
+ for (int32_t index = 0; index < 2; index++)
+ {
+ // store in order of index
+ bool found = false;
+ for (auto out : unique_outs)
+ {
+ auto unique_out = loco::must_cast<luci::CircleUniqueOut *>(out);
+ if (unique_out->index() == index)
+ {
+ outputs_vec.push_back(get_tensor_index(unique_out));
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ {
+ INTERNAL_EXN("Invalid Unique output");
+ }
+ }
+
+ auto inputs = builder.CreateVector(inputs_vec);
+ auto outputs = builder.CreateVector(outputs_vec);
+ auto options = CreateUniqueOptions(builder, to_circle_tensortype(node->idx_out_type()));
+ auto op_offset = CreateOperator(builder, op_idx, inputs, outputs,
+ circle::BuiltinOptions_UniqueOptions, options.Union());
+ gd._operators.push_back(op_offset);
+}
+
void OperationExporter::visit(luci::CircleUnpack *node)
{
LOGGER(l);
diff --git a/compiler/luci/export/src/CircleTensorExporter.cpp b/compiler/luci/export/src/CircleTensorExporter.cpp
index 5cad3920b..dc8c2fbc9 100644
--- a/compiler/luci/export/src/CircleTensorExporter.cpp
+++ b/compiler/luci/export/src/CircleTensorExporter.cpp
@@ -302,7 +302,10 @@ encodeQuantizationParameters(FlatBufferBuilder &builder, luci::CircleQuantParam
scale = builder.CreateVector(quantparam->scale);
zero_point = builder.CreateVector(quantparam->zerop);
}
- return circle::CreateQuantizationParameters(builder, min, max, scale, zero_point);
+ // Note: QuantizationDetails is not supported
+ return circle::CreateQuantizationParameters(builder, min, max, scale, zero_point,
+ circle::QuantizationDetails::QuantizationDetails_NONE,
+ 0, quantparam->quantized_dimension);
}
void exportOpDefinedTensor(const CircleTensoInfo &info, FlatBufferBuilder &builder,
diff --git a/compiler/luci/import/include/luci/Import/Nodes.h b/compiler/luci/import/include/luci/Import/Nodes.h
index 2719a5aec..825c2147d 100644
--- a/compiler/luci/import/include/luci/Import/Nodes.h
+++ b/compiler/luci/import/include/luci/Import/Nodes.h
@@ -73,6 +73,7 @@
#include "Nodes/CircleMirrorPad.h"
#include "Nodes/CircleMul.h"
#include "Nodes/CircleNeg.h"
+#include "Nodes/CircleNonMaxSuppressionV4.h"
#include "Nodes/CircleNotEqual.h"
#include "Nodes/CircleOneHot.h"
#include "Nodes/CirclePack.h"
@@ -120,6 +121,7 @@
#include "Nodes/CircleTopKV2.h"
#include "Nodes/CircleTranspose.h"
#include "Nodes/CircleTransposeConv.h"
+#include "Nodes/CircleUnique.h"
#include "Nodes/CircleUnpack.h"
#include "Nodes/CircleWhere.h"
#include "Nodes/CircleWhile.h"
diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleNonMaxSuppressionV4.h b/compiler/luci/import/include/luci/Import/Nodes/CircleNonMaxSuppressionV4.h
new file mode 100644
index 000000000..f193aae35
--- /dev/null
+++ b/compiler/luci/import/include/luci/Import/Nodes/CircleNonMaxSuppressionV4.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LUCI_IMPORT_OP_CIRCLE_NON_MAX_SUPPRESSION_V4_H__
+#define __LUCI_IMPORT_OP_CIRCLE_NON_MAX_SUPPRESSION_V4_H__
+
+#include "luci/Import/GraphBuilderBase.h"
+
+namespace luci
+{
+
+class CircleNonMaxSuppressionV4GraphBuilder : public GraphBuilderBase
+{
+public:
+ bool validate(const ValidateArgs &args) const final;
+
+ void build(const circle::OperatorT &op, GraphBuilderContext *context) const final;
+};
+
+} // namespace luci
+
+#endif // __LUCI_IMPORT_OP_CIRCLE_NON_MAX_SUPPRESSION_V4_H__
diff --git a/compiler/luci/import/include/luci/Import/Nodes/CircleUnique.h b/compiler/luci/import/include/luci/Import/Nodes/CircleUnique.h
new file mode 100644
index 000000000..ed5b5035d
--- /dev/null
+++ b/compiler/luci/import/include/luci/Import/Nodes/CircleUnique.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LUCI_IMPORT_OP_CIRCLE_UNIQUE_H__
+#define __LUCI_IMPORT_OP_CIRCLE_UNIQUE_H__
+
+#include "luci/Import/GraphBuilderBase.h"
+
+namespace luci
+{
+
+class CircleUniqueGraphBuilder : public GraphBuilderBase
+{
+public:
+ bool validate(const ValidateArgs &args) const final;
+
+ void build(const circle::OperatorT &op, GraphBuilderContext *context) const final;
+};
+
+} // namespace luci
+
+#endif // __LUCI_IMPORT_OP_CIRCLE_UNIQUE_H__
diff --git a/compiler/luci/import/src/CircleReader.cpp b/compiler/luci/import/src/CircleReader.cpp
index 81e945dd1..bc7f39762 100644
--- a/compiler/luci/import/src/CircleReader.cpp
+++ b/compiler/luci/import/src/CircleReader.cpp
@@ -156,6 +156,7 @@ luci_quantparam(const circle::QuantizationParametersT *quantization)
const auto &max = quantization->max;
const auto &scale = quantization->scale;
const auto &zero_point = quantization->zero_point;
+ const auto &quantized_dimension = quantization->quantized_dimension;
if ((!min.empty() && !max.empty()) || (!scale.empty() && !zero_point.empty()))
{
@@ -165,6 +166,7 @@ luci_quantparam(const circle::QuantizationParametersT *quantization)
quantparam->max = max;
quantparam->scale = scale;
quantparam->zerop = zero_point;
+ quantparam->quantized_dimension = quantized_dimension;
return quantparam;
}
diff --git a/compiler/luci/import/src/GraphBuilderRegistry.cpp b/compiler/luci/import/src/GraphBuilderRegistry.cpp
index d29557f74..cc328cc16 100644
--- a/compiler/luci/import/src/GraphBuilderRegistry.cpp
+++ b/compiler/luci/import/src/GraphBuilderRegistry.cpp
@@ -82,6 +82,7 @@ GraphBuilderRegistry::GraphBuilderRegistry()
CIRCLE_NODE(MIRROR_PAD, CircleMirrorPadGraphBuilder); // 100
CIRCLE_NODE(MUL, CircleMulGraphBuilder); // 18
CIRCLE_NODE(NEG, CircleNegGraphBuilder); // 59
+ CIRCLE_NODE(NON_MAX_SUPPRESSION_V4, CircleNonMaxSuppressionV4GraphBuilder); // 120,
CIRCLE_NODE(NOT_EQUAL, CircleNotEqualGraphBuilder); // 72
CIRCLE_NODE(ONE_HOT, CircleOneHotGraphBuilder); // 85
CIRCLE_NODE(PACK, CirclePackGraphBuilder); // 83
@@ -129,6 +130,7 @@ GraphBuilderRegistry::GraphBuilderRegistry()
CIRCLE_NODE(TOPK_V2, CircleTopKV2GraphBuilder); // 48
CIRCLE_NODE(TRANSPOSE, CircleTransposeGraphBuilder); // 39
CIRCLE_NODE(TRANSPOSE_CONV, CircleTransposeConvGraphBuilder); // 67
+ CIRCLE_NODE(UNIQUE, CircleUniqueGraphBuilder); // 103
CIRCLE_NODE(UNPACK, CircleUnpackGraphBuilder); // 88
CIRCLE_NODE(WHERE, CircleWhereGraphBuilder); // 109
CIRCLE_NODE(WHILE, CircleWhileGraphBuilder); // 119
@@ -155,10 +157,8 @@ GraphBuilderRegistry::GraphBuilderRegistry()
// BuiltinOperator_ARG_MAX = 56,
// BuiltinOperator_PADV2 = 60,
// BuiltinOperator_FAKE_QUANT = 80,
- // BuiltinOperator_UNIQUE = 103,
// BuiltinOperator_QUANTIZE = 114,
// BuiltinOperator_HARD_SWISH = 117,
- // BuiltinOperator_NON_MAX_SUPPRESSION_V4 = 120,
// BuiltinOperator_NON_MAX_SUPPRESSION_V5 = 121,
// BuiltinOperator_DENSIFY = 124,
}
diff --git a/compiler/luci/import/src/Importer.test.cpp b/compiler/luci/import/src/Importer.test.cpp
index 4426e15fd..8366546f0 100644
--- a/compiler/luci/import/src/Importer.test.cpp
+++ b/compiler/luci/import/src/Importer.test.cpp
@@ -20,4 +20,9 @@
#include <gtest/gtest.h>
-TEST(TensorFlowLiteImport, Dummy) { luci::Importer import; }
+TEST(TensorFlowLiteImport, Dummy)
+{
+ luci::Importer import;
+
+ SUCCEED();
+}
diff --git a/compiler/luci/import/src/Nodes/CircleAbs.cpp b/compiler/luci/import/src/Nodes/CircleAbs.cpp
index 9054986bd..3556dc7fa 100644
--- a/compiler/luci/import/src/Nodes/CircleAbs.cpp
+++ b/compiler/luci/import/src/Nodes/CircleAbs.cpp
@@ -36,7 +36,7 @@ CircleNode *CircleAbsGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleAbs>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleAdd.cpp b/compiler/luci/import/src/Nodes/CircleAdd.cpp
index 3b1bb734f..b767d4af2 100644
--- a/compiler/luci/import/src/Nodes/CircleAdd.cpp
+++ b/compiler/luci/import/src/Nodes/CircleAdd.cpp
@@ -36,8 +36,8 @@ CircleNode *CircleAddGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleAdd>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
const auto *options = op.builtin_options.AsAddOptions();
node->fusedActivationFunction(luci_actfunc(options->fused_activation_function));
diff --git a/compiler/luci/import/src/Nodes/CircleArgMax.cpp b/compiler/luci/import/src/Nodes/CircleArgMax.cpp
index 2679827e2..10e8516f4 100644
--- a/compiler/luci/import/src/Nodes/CircleArgMax.cpp
+++ b/compiler/luci/import/src/Nodes/CircleArgMax.cpp
@@ -36,8 +36,8 @@ CircleNode *CircleArgMaxGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleArgMax>();
- node->input(inputs[0]);
- node->dimension(inputs[1]);
+ node->input(inputs.at(0));
+ node->dimension(inputs.at(1));
const auto *options = op.builtin_options.AsArgMaxOptions();
node->output_type(luci_datatype(options->output_type));
diff --git a/compiler/luci/import/src/Nodes/CircleArgMin.cpp b/compiler/luci/import/src/Nodes/CircleArgMin.cpp
index 4d85bbff0..5ff534dbb 100644
--- a/compiler/luci/import/src/Nodes/CircleArgMin.cpp
+++ b/compiler/luci/import/src/Nodes/CircleArgMin.cpp
@@ -36,8 +36,8 @@ CircleNode *CircleArgMinGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleArgMin>();
- node->input(inputs[0]);
- node->dimension(inputs[1]);
+ node->input(inputs.at(0));
+ node->dimension(inputs.at(1));
const auto *options = op.builtin_options.AsArgMinOptions();
node->output_type(luci_datatype(options->output_type));
diff --git a/compiler/luci/import/src/Nodes/CircleAveragePool2D.cpp b/compiler/luci/import/src/Nodes/CircleAveragePool2D.cpp
index cfc3cf126..ad011f71f 100644
--- a/compiler/luci/import/src/Nodes/CircleAveragePool2D.cpp
+++ b/compiler/luci/import/src/Nodes/CircleAveragePool2D.cpp
@@ -34,7 +34,7 @@ CircleNode *CircleAveragePool2DGraphBuilder::build_node(const circle::OperatorT
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleAveragePool2D>();
- node->value(inputs[0]);
+ node->value(inputs.at(0));
const auto *options = op.builtin_options.AsPool2DOptions();
node->padding(luci_padding(options->padding));
diff --git a/compiler/luci/import/src/Nodes/CircleBCQFullyConnected.cpp b/compiler/luci/import/src/Nodes/CircleBCQFullyConnected.cpp
index 7cc077ed6..16ecebd5c 100644
--- a/compiler/luci/import/src/Nodes/CircleBCQFullyConnected.cpp
+++ b/compiler/luci/import/src/Nodes/CircleBCQFullyConnected.cpp
@@ -37,11 +37,11 @@ CircleNode *CircleBCQFullyConnectedGraphBuilder::build_node(const circle::Operat
{
auto *node = graph->nodes()->create<CircleBCQFullyConnected>();
- node->input(inputs[0]);
- node->weights_scales(inputs[1]);
- node->weights_binary(inputs[2]);
- node->bias(inputs[3]);
- node->weights_clusters(inputs[4]);
+ node->input(inputs.at(0));
+ node->weights_scales(inputs.at(1));
+ node->weights_binary(inputs.at(2));
+ node->bias(inputs.at(3));
+ node->weights_clusters(inputs.at(4));
// TODO Find and move to appropriate place for setting optional input
if (auto bias = dynamic_cast<luci::CircleOutputExclude *>(node->bias()))
diff --git a/compiler/luci/import/src/Nodes/CircleBCQGather.cpp b/compiler/luci/import/src/Nodes/CircleBCQGather.cpp
index c6d2ab559..464f1ac18 100644
--- a/compiler/luci/import/src/Nodes/CircleBCQGather.cpp
+++ b/compiler/luci/import/src/Nodes/CircleBCQGather.cpp
@@ -37,10 +37,10 @@ CircleNode *CircleBCQGatherGraphBuilder::build_node(const circle::OperatorT &op,
{
auto *node = graph->nodes()->create<CircleBCQGather>();
- node->input_scales(inputs[0]);
- node->input_binary(inputs[1]);
- node->indices(inputs[2]);
- node->input_clusters(inputs[3]);
+ node->input_scales(inputs.at(0));
+ node->input_binary(inputs.at(1));
+ node->indices(inputs.at(2));
+ node->input_clusters(inputs.at(3));
const auto *options = op.builtin_options.AsBCQGatherOptions();
node->input_hidden_size(options->input_hidden_size);
diff --git a/compiler/luci/import/src/Nodes/CircleBatchMatMul.cpp b/compiler/luci/import/src/Nodes/CircleBatchMatMul.cpp
index 6026b2a72..330775691 100644
--- a/compiler/luci/import/src/Nodes/CircleBatchMatMul.cpp
+++ b/compiler/luci/import/src/Nodes/CircleBatchMatMul.cpp
@@ -34,8 +34,8 @@ CircleNode *CircleBatchMatMulGraphBuilder::build_node(const circle::OperatorT &o
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleBatchMatMul>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
const auto *options = op.builtin_options.AsBatchMatMulOptions();
node->adj_x(options->adjoint_lhs);
diff --git a/compiler/luci/import/src/Nodes/CircleBatchToSpaceND.cpp b/compiler/luci/import/src/Nodes/CircleBatchToSpaceND.cpp
index 4bbfadf64..8c2039fff 100644
--- a/compiler/luci/import/src/Nodes/CircleBatchToSpaceND.cpp
+++ b/compiler/luci/import/src/Nodes/CircleBatchToSpaceND.cpp
@@ -33,7 +33,7 @@ bool CircleBatchToSpaceNDGraphBuilder::validate(const ValidateArgs &args) const
// input 1 and 2 should have INT32/INT64 type
const auto &tensors = args.reader.tensors();
- const auto &tensor_1 = tensors.at(inputs[1]);
+ const auto &tensor_1 = tensors.at(inputs.at(1));
switch (tensor_1->type)
{
case circle::TensorType_INT32:
@@ -42,7 +42,7 @@ bool CircleBatchToSpaceNDGraphBuilder::validate(const ValidateArgs &args) const
default:
return false;
}
- const auto &tensor_2 = tensors.at(inputs[2]);
+ const auto &tensor_2 = tensors.at(inputs.at(2));
switch (tensor_2->type)
{
case circle::TensorType_INT32:
@@ -53,7 +53,7 @@ bool CircleBatchToSpaceNDGraphBuilder::validate(const ValidateArgs &args) const
}
// Only support input shape dimension 3 and 4 only
- const auto &tensor_0 = tensors.at(inputs[0]);
+ const auto &tensor_0 = tensors.at(inputs.at(0));
const auto t_0_s = tensor_0->shape.size();
if (t_0_s != 3 && t_0_s != 4)
return false;
@@ -68,9 +68,9 @@ CircleNode *CircleBatchToSpaceNDGraphBuilder::build_node(const circle::OperatorT
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleBatchToSpaceND>();
- node->input(inputs[0]);
- node->block_shape(inputs[1]);
- node->crops(inputs[2]);
+ node->input(inputs.at(0));
+ node->block_shape(inputs.at(1));
+ node->crops(inputs.at(2));
// No options for BatchToSpaceND
diff --git a/compiler/luci/import/src/Nodes/CircleCast.cpp b/compiler/luci/import/src/Nodes/CircleCast.cpp
index a4d09b505..7bdb63044 100644
--- a/compiler/luci/import/src/Nodes/CircleCast.cpp
+++ b/compiler/luci/import/src/Nodes/CircleCast.cpp
@@ -47,7 +47,7 @@ bool CircleCastGraphBuilder::validate(const ValidateArgs &args) const
const circle::TensorT &output_tensor = *tensors[outputs[0]];
auto name = tensor_name(output_tensor);
- const auto &tensor_in = tensors.at(inputs[0]);
+ const auto &tensor_in = tensors.at(inputs.at(0));
if (tensor_in->type != options->in_data_type)
{
if (settings->get(luci::UserSettings::Key::DisableValidation))
@@ -77,7 +77,7 @@ CircleNode *CircleCastGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleCast>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
const auto *options = op.builtin_options.AsCastOptions();
if (options != nullptr)
@@ -87,7 +87,7 @@ CircleNode *CircleCastGraphBuilder::build_node(const circle::OperatorT &op,
}
else
{
- node->in_data_type(inputs[0]->dtype());
+ node->in_data_type(inputs.at(0)->dtype());
node->out_data_type(loco::DataType::Unknown);
// type inference should use node->dtype() for Unknown
// export should use BuiltinOptions_NONE for Unknown
diff --git a/compiler/luci/import/src/Nodes/CircleCeil.cpp b/compiler/luci/import/src/Nodes/CircleCeil.cpp
index d3d6cd945..2e1aaa295 100644
--- a/compiler/luci/import/src/Nodes/CircleCeil.cpp
+++ b/compiler/luci/import/src/Nodes/CircleCeil.cpp
@@ -42,7 +42,7 @@ CircleNode *CircleCeilGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleCeil>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleConv2D.cpp b/compiler/luci/import/src/Nodes/CircleConv2D.cpp
index 42c5c265a..9516ef16a 100644
--- a/compiler/luci/import/src/Nodes/CircleConv2D.cpp
+++ b/compiler/luci/import/src/Nodes/CircleConv2D.cpp
@@ -39,11 +39,11 @@ CircleNode *CircleConv2DGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleConv2D>();
- node->input(inputs[0]);
- node->filter(inputs[1]);
+ node->input(inputs.at(0));
+ node->filter(inputs.at(1));
// For now, bias is required (checked in `verify` method).
assert(inputs.size() == 3);
- node->bias(inputs[2]);
+ node->bias(inputs.at(2));
const auto *options = op.builtin_options.AsConv2DOptions();
node->padding(luci_padding(options->padding));
diff --git a/compiler/luci/import/src/Nodes/CircleCos.cpp b/compiler/luci/import/src/Nodes/CircleCos.cpp
index 5f61cc7f6..27d60c62c 100644
--- a/compiler/luci/import/src/Nodes/CircleCos.cpp
+++ b/compiler/luci/import/src/Nodes/CircleCos.cpp
@@ -36,7 +36,7 @@ CircleNode *CircleCosGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleCos>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
// No options for Cos
diff --git a/compiler/luci/import/src/Nodes/CircleDepthToSpace.cpp b/compiler/luci/import/src/Nodes/CircleDepthToSpace.cpp
index 827b63468..49d31bb99 100644
--- a/compiler/luci/import/src/Nodes/CircleDepthToSpace.cpp
+++ b/compiler/luci/import/src/Nodes/CircleDepthToSpace.cpp
@@ -40,7 +40,7 @@ bool CircleDepthToSpaceGraphBuilder::validate(const ValidateArgs &args) const
const auto &tensors = args.reader.tensors();
- if (tensors[outputs[0]]->type != tensors[inputs[0]]->type)
+ if (tensors[outputs[0]]->type != tensors[inputs.at(0)]->type)
{
return false;
}
@@ -56,7 +56,7 @@ CircleNode *CircleDepthToSpaceGraphBuilder::build_node(const circle::OperatorT &
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleDepthToSpace>();
- node->input(inputs[0]);
+ node->input(inputs.at(0));
const auto *options = op.builtin_options.AsDepthToSpaceOptions();
node->block_size(options->block_size);
diff --git a/compiler/luci/import/src/Nodes/CircleDepthwiseConv2D.cpp b/compiler/luci/import/src/Nodes/CircleDepthwiseConv2D.cpp
index 2b13f9ebb..53f85f2f5 100644
--- a/compiler/luci/import/src/Nodes/CircleDepthwiseConv2D.cpp
+++ b/compiler/luci/import/src/Nodes/CircleDepthwiseConv2D.cpp
@@ -40,11 +40,11 @@ CircleNode *CircleDepthwiseConv2DGraphBuilder::build_node(const circle::Operator
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleDepthwiseConv2D>();
- node->input(inputs[0]);
- node->filter(inputs[1]);
+ node->input(inputs.at(0));
+ node->filter(inputs.at(1));
if (inputs.size() != 3)
throw oops::UserExn("DepthwiseConv2d without bias is unsupported");
- node->bias(inputs[2]);
+ node->bias(inputs.at(2));
const auto *options = op.builtin_options.AsDepthwiseConv2DOptions();
node->padding(luci_padding(options->padding));
diff --git a/compiler/luci/import/src/Nodes/CircleDiv.cpp b/compiler/luci/import/src/Nodes/CircleDiv.cpp
index d09cfb815..615c224d7 100644
--- a/compiler/luci/import/src/Nodes/CircleDiv.cpp
+++ b/compiler/luci/import/src/Nodes/CircleDiv.cpp
@@ -37,8 +37,8 @@ CircleNode *CircleDivGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto node = graph->nodes()->create<CircleDiv>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
const auto *options = op.builtin_options.AsDivOptions();
node->fusedActivationFunction(luci_actfunc(options->fused_activation_function));
diff --git a/compiler/luci/import/src/Nodes/CircleElu.cpp b/compiler/luci/import/src/Nodes/CircleElu.cpp
index 37a290cb1..919e95ee4 100644
--- a/compiler/luci/import/src/Nodes/CircleElu.cpp
+++ b/compiler/luci/import/src/Nodes/CircleElu.cpp
@@ -35,7 +35,7 @@ bool CircleEluGraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
+ const auto &tensor = tensors.at(inputs.at(0));
switch (tensor->type)
{
@@ -56,7 +56,7 @@ CircleNode *CircleEluGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleElu>();
- node->features(inputs[0]);
+ node->features(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleEqual.cpp b/compiler/luci/import/src/Nodes/CircleEqual.cpp
index a53f6e94b..1db33b8ac 100644
--- a/compiler/luci/import/src/Nodes/CircleEqual.cpp
+++ b/compiler/luci/import/src/Nodes/CircleEqual.cpp
@@ -34,7 +34,7 @@ bool CircleEqualGraphBuilder::validate(const ValidateArgs &args) const
const auto &tensors = args.reader.tensors();
- return tensors[inputs[0]]->type == tensors[inputs[1]]->type;
+ return tensors[inputs.at(0)]->type == tensors[inputs.at(1)]->type;
}
CircleNode *CircleEqualGraphBuilder::build_node(const circle::OperatorT &,
@@ -42,8 +42,8 @@ CircleNode *CircleEqualGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleEqual>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleExp.cpp b/compiler/luci/import/src/Nodes/CircleExp.cpp
index a32851458..2c031d6b3 100644
--- a/compiler/luci/import/src/Nodes/CircleExp.cpp
+++ b/compiler/luci/import/src/Nodes/CircleExp.cpp
@@ -31,7 +31,7 @@ bool CircleExpGraphBuilder::validate(const ValidateArgs &args) const
// input type check
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
+ const auto &tensor = tensors.at(inputs.at(0));
switch (tensor->type)
{
case circle::TensorType_FLOAT16:
@@ -51,7 +51,7 @@ CircleNode *CircleExpGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleExp>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleExpandDims.cpp b/compiler/luci/import/src/Nodes/CircleExpandDims.cpp
index 1cef67a83..ab537c710 100644
--- a/compiler/luci/import/src/Nodes/CircleExpandDims.cpp
+++ b/compiler/luci/import/src/Nodes/CircleExpandDims.cpp
@@ -34,7 +34,7 @@ bool CircleExpandDimsGraphBuilder::validate(const ValidateArgs &args) const
const auto &tensors = args.reader.tensors();
- return tensors[inputs[1]]->type == circle::TensorType_INT32;
+ return tensors[inputs.at(1)]->type == circle::TensorType_INT32;
}
CircleNode *CircleExpandDimsGraphBuilder::build_node(const circle::OperatorT &,
@@ -42,8 +42,8 @@ CircleNode *CircleExpandDimsGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleExpandDims>();
- node->input(inputs[0]);
- node->axis(inputs[1]);
+ node->input(inputs.at(0));
+ node->axis(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleFill.cpp b/compiler/luci/import/src/Nodes/CircleFill.cpp
index 6c3d3a247..95d5b876b 100644
--- a/compiler/luci/import/src/Nodes/CircleFill.cpp
+++ b/compiler/luci/import/src/Nodes/CircleFill.cpp
@@ -37,8 +37,8 @@ CircleNode *CircleFillGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleFill>();
- node->dims(inputs[0]);
- node->value(inputs[1]);
+ node->dims(inputs.at(0));
+ node->value(inputs.at(1));
const auto *options = op.builtin_options.AsFillOptions();
(void)options;
diff --git a/compiler/luci/import/src/Nodes/CircleFloor.cpp b/compiler/luci/import/src/Nodes/CircleFloor.cpp
index 302a9eae3..ce756b3b1 100644
--- a/compiler/luci/import/src/Nodes/CircleFloor.cpp
+++ b/compiler/luci/import/src/Nodes/CircleFloor.cpp
@@ -42,7 +42,7 @@ CircleNode *CircleFloorGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleFloor>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleFloorDiv.cpp b/compiler/luci/import/src/Nodes/CircleFloorDiv.cpp
index 875197890..55f385d60 100644
--- a/compiler/luci/import/src/Nodes/CircleFloorDiv.cpp
+++ b/compiler/luci/import/src/Nodes/CircleFloorDiv.cpp
@@ -39,8 +39,8 @@ bool CircleFloorDivGraphBuilder::validate(const ValidateArgs &args) const
}
const auto &tensors = args.reader.tensors();
- const auto &tensor_in_0 = tensors.at(inputs[0]);
- const auto &tensor_in_1 = tensors.at(inputs[1]);
+ const auto &tensor_in_0 = tensors.at(inputs.at(0));
+ const auto &tensor_in_1 = tensors.at(inputs.at(1));
const auto &tensor_out = tensors.at(outputs[0]);
if (tensor_in_0->type != tensor_in_1->type)
@@ -59,8 +59,8 @@ CircleNode *CircleFloorDivGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleFloorDiv>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleFloorMod.cpp b/compiler/luci/import/src/Nodes/CircleFloorMod.cpp
index 3ccdce0cd..2101e417e 100644
--- a/compiler/luci/import/src/Nodes/CircleFloorMod.cpp
+++ b/compiler/luci/import/src/Nodes/CircleFloorMod.cpp
@@ -33,8 +33,8 @@ bool CircleFloorModGraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor_in_0 = tensors.at(inputs[0]);
- const auto &tensor_in_1 = tensors.at(inputs[1]);
+ const auto &tensor_in_0 = tensors.at(inputs.at(0));
+ const auto &tensor_in_1 = tensors.at(inputs.at(1));
if (tensor_in_0->type != tensor_in_1->type)
return false;
@@ -48,8 +48,8 @@ CircleNode *CircleFloorModGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleFloorMod>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleFullyConnected.cpp b/compiler/luci/import/src/Nodes/CircleFullyConnected.cpp
index 8937e78f1..65a863bde 100644
--- a/compiler/luci/import/src/Nodes/CircleFullyConnected.cpp
+++ b/compiler/luci/import/src/Nodes/CircleFullyConnected.cpp
@@ -38,9 +38,9 @@ CircleNode *CircleFullyConnectedGraphBuilder::build_node(const circle::OperatorT
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleFullyConnected>();
- node->input(inputs[0]);
- node->weights(inputs[1]);
- node->bias(inputs[2]); // bias is optional
+ node->input(inputs.at(0));
+ node->weights(inputs.at(1));
+ node->bias(inputs.at(2)); // bias is optional
// TODO Find and move to appropriate place for setting optional input
if (auto bias = dynamic_cast<luci::CircleOutputExclude *>(node->bias()))
diff --git a/compiler/luci/import/src/Nodes/CircleGather.cpp b/compiler/luci/import/src/Nodes/CircleGather.cpp
index 1caa05ec2..75447a38a 100644
--- a/compiler/luci/import/src/Nodes/CircleGather.cpp
+++ b/compiler/luci/import/src/Nodes/CircleGather.cpp
@@ -56,8 +56,8 @@ CircleNode *CircleGatherGraphBuilder::build_node(const circle::OperatorT &op,
{
auto *node = graph->nodes()->create<CircleGather>();
- node->params(inputs[0]);
- node->indices(inputs[1]);
+ node->params(inputs.at(0));
+ node->indices(inputs.at(1));
const auto *options = op.builtin_options.AsGatherOptions();
node->axis(options->axis);
diff --git a/compiler/luci/import/src/Nodes/CircleGatherNd.cpp b/compiler/luci/import/src/Nodes/CircleGatherNd.cpp
index 621d4ae92..981adbf63 100644
--- a/compiler/luci/import/src/Nodes/CircleGatherNd.cpp
+++ b/compiler/luci/import/src/Nodes/CircleGatherNd.cpp
@@ -36,7 +36,7 @@ bool CircleGatherNdGraphBuilder::validate(const ValidateArgs &args) const
if (outputs.size() != 1)
return false;
- auto &indices_tensor = args.reader.tensors()[inputs[1]];
+ auto &indices_tensor = args.reader.tensors()[inputs.at(1)];
if (!(indices_tensor->type == circle::TensorType::TensorType_INT32 ||
indices_tensor->type == circle::TensorType::TensorType_INT64))
@@ -53,8 +53,8 @@ CircleNode *CircleGatherNdGraphBuilder::build_node(const circle::OperatorT &,
{
auto *node = graph->nodes()->create<CircleGatherNd>();
- node->params(inputs[0]);
- node->indices(inputs[1]);
+ node->params(inputs.at(0));
+ node->indices(inputs.at(1));
// GatherNd options empty
diff --git a/compiler/luci/import/src/Nodes/CircleGreater.cpp b/compiler/luci/import/src/Nodes/CircleGreater.cpp
index 88107589c..1ad0467e4 100644
--- a/compiler/luci/import/src/Nodes/CircleGreater.cpp
+++ b/compiler/luci/import/src/Nodes/CircleGreater.cpp
@@ -43,7 +43,7 @@ bool CircleGreaterGraphBuilder::validate(const ValidateArgs &args) const
const auto &tensors = args.reader.tensors();
- if (tensors[inputs[0]]->type != tensors[inputs[1]]->type)
+ if (tensors[inputs.at(0)]->type != tensors[inputs.at(1)]->type)
return false;
// NOTE: real models do have output dtype NOT BOOL
@@ -67,8 +67,8 @@ CircleNode *CircleGreaterGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleGreater>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleGreaterEqual.cpp b/compiler/luci/import/src/Nodes/CircleGreaterEqual.cpp
index dff1510c5..0ac63b017 100644
--- a/compiler/luci/import/src/Nodes/CircleGreaterEqual.cpp
+++ b/compiler/luci/import/src/Nodes/CircleGreaterEqual.cpp
@@ -40,7 +40,7 @@ bool CircleGreaterEqualGraphBuilder::validate(const ValidateArgs &args) const
const auto &tensors = args.reader.tensors();
- if (tensors[inputs[0]]->type != tensors[inputs[1]]->type)
+ if (tensors[inputs.at(0)]->type != tensors[inputs.at(1)]->type)
{
return false;
}
@@ -53,8 +53,8 @@ CircleNode *CircleGreaterEqualGraphBuilder::build_node(const circle::OperatorT &
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleGreaterEqual>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleIf.cpp b/compiler/luci/import/src/Nodes/CircleIf.cpp
index d6090640d..db9ffe1cd 100644
--- a/compiler/luci/import/src/Nodes/CircleIf.cpp
+++ b/compiler/luci/import/src/Nodes/CircleIf.cpp
@@ -43,7 +43,7 @@ bool CircleIfGraphBuilder::validate(const ValidateArgs &args) const
// input 0 should be BOOL type
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
+ const auto &tensor = tensors.at(inputs.at(0));
if (tensor->type != circle::TensorType_BOOL)
return false;
diff --git a/compiler/luci/import/src/Nodes/CircleInstanceNorm.cpp b/compiler/luci/import/src/Nodes/CircleInstanceNorm.cpp
index b95c54c89..6349fd3b7 100644
--- a/compiler/luci/import/src/Nodes/CircleInstanceNorm.cpp
+++ b/compiler/luci/import/src/Nodes/CircleInstanceNorm.cpp
@@ -38,9 +38,9 @@ CircleNode *CircleInstanceNormGraphBuilder::build_node(const circle::OperatorT &
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleInstanceNorm>();
- node->input(inputs[0]);
- node->gamma(inputs[1]);
- node->beta(inputs[2]);
+ node->input(inputs.at(0));
+ node->gamma(inputs.at(1));
+ node->beta(inputs.at(2));
const auto *options = op.builtin_options.AsInstanceNormOptions();
node->epsilon(options->epsilon);
diff --git a/compiler/luci/import/src/Nodes/CircleL2Normalize.cpp b/compiler/luci/import/src/Nodes/CircleL2Normalize.cpp
index fe10a8572..e4fdc200c 100644
--- a/compiler/luci/import/src/Nodes/CircleL2Normalize.cpp
+++ b/compiler/luci/import/src/Nodes/CircleL2Normalize.cpp
@@ -46,7 +46,7 @@ CircleNode *CircleL2NormalizeGraphBuilder::build_node(const circle::OperatorT &o
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleL2Normalize>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
const auto *options = op.builtin_options.AsL2NormOptions();
node->fusedActivationFunction(luci_actfunc(options->fused_activation_function));
diff --git a/compiler/luci/import/src/Nodes/CircleL2Pool2D.cpp b/compiler/luci/import/src/Nodes/CircleL2Pool2D.cpp
index 023206695..202d9d6fb 100644
--- a/compiler/luci/import/src/Nodes/CircleL2Pool2D.cpp
+++ b/compiler/luci/import/src/Nodes/CircleL2Pool2D.cpp
@@ -38,7 +38,7 @@ CircleNode *CircleL2Pool2DGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleL2Pool2D>();
- node->value(inputs[0]);
+ node->value(inputs.at(0));
const auto *options = op.builtin_options.AsPool2DOptions();
node->padding(luci_padding(options->padding));
diff --git a/compiler/luci/import/src/Nodes/CircleLeakyRelu.cpp b/compiler/luci/import/src/Nodes/CircleLeakyRelu.cpp
index 4957ceae0..ad4979f39 100644
--- a/compiler/luci/import/src/Nodes/CircleLeakyRelu.cpp
+++ b/compiler/luci/import/src/Nodes/CircleLeakyRelu.cpp
@@ -39,7 +39,7 @@ CircleNode *CircleLeakyReluGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleLeakyRelu>();
- node->features(inputs[0]);
+ node->features(inputs.at(0));
const auto *options = op.builtin_options.AsLeakyReluOptions();
node->alpha(options->alpha);
diff --git a/compiler/luci/import/src/Nodes/CircleLess.cpp b/compiler/luci/import/src/Nodes/CircleLess.cpp
index 40ad28c6e..506036908 100644
--- a/compiler/luci/import/src/Nodes/CircleLess.cpp
+++ b/compiler/luci/import/src/Nodes/CircleLess.cpp
@@ -39,7 +39,7 @@ bool CircleLessGraphBuilder::validate(const ValidateArgs &args) const
}
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
+ const auto &tensor = tensors.at(inputs.at(0));
switch (tensor->type)
{
@@ -56,7 +56,7 @@ bool CircleLessGraphBuilder::validate(const ValidateArgs &args) const
return false;
}
- if (tensors[inputs[1]]->type != tensor->type)
+ if (tensors[inputs.at(1)]->type != tensor->type)
{
return false;
}
@@ -69,8 +69,8 @@ CircleNode *CircleLessGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleLess>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleLessEqual.cpp b/compiler/luci/import/src/Nodes/CircleLessEqual.cpp
index 13e995069..9b4f934a5 100644
--- a/compiler/luci/import/src/Nodes/CircleLessEqual.cpp
+++ b/compiler/luci/import/src/Nodes/CircleLessEqual.cpp
@@ -40,7 +40,7 @@ bool CircleLessEqualGraphBuilder::validate(const ValidateArgs &args) const
const auto &tensors = args.reader.tensors();
- if (tensors[inputs[0]]->type != tensors[inputs[1]]->type)
+ if (tensors[inputs.at(0)]->type != tensors[inputs.at(1)]->type)
{
return false;
}
@@ -53,8 +53,8 @@ CircleNode *CircleLessEqualGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleLessEqual>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleLocalResponseNormalization.cpp b/compiler/luci/import/src/Nodes/CircleLocalResponseNormalization.cpp
index 7b1f0db56..0e32f62de 100644
--- a/compiler/luci/import/src/Nodes/CircleLocalResponseNormalization.cpp
+++ b/compiler/luci/import/src/Nodes/CircleLocalResponseNormalization.cpp
@@ -37,7 +37,7 @@ CircleNode *CircleLocalResponseNormalizationGraphBuilder::build_node(
const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleLocalResponseNormalization>();
- node->input(inputs[0]);
+ node->input(inputs.at(0));
const auto *options = op.builtin_options.AsLocalResponseNormalizationOptions();
node->radius(options->radius);
diff --git a/compiler/luci/import/src/Nodes/CircleLog.cpp b/compiler/luci/import/src/Nodes/CircleLog.cpp
index 21408327d..346fc43bb 100644
--- a/compiler/luci/import/src/Nodes/CircleLog.cpp
+++ b/compiler/luci/import/src/Nodes/CircleLog.cpp
@@ -35,7 +35,7 @@ bool CircleLogGraphBuilder::validate(const ValidateArgs &args) const
// Must be one of bfloat16, half, float32, float64, complex64, complex128.
// Currently circle supports half(float16), float32, float64, complex64.
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
+ const auto &tensor = tensors.at(inputs.at(0));
switch (tensor->type)
{
case circle::TensorType_FLOAT16:
@@ -55,7 +55,7 @@ CircleNode *CircleLogGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleLog>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
// No options for Log
diff --git a/compiler/luci/import/src/Nodes/CircleLogSoftmax.cpp b/compiler/luci/import/src/Nodes/CircleLogSoftmax.cpp
index e738c4a0c..ef69e868a 100644
--- a/compiler/luci/import/src/Nodes/CircleLogSoftmax.cpp
+++ b/compiler/luci/import/src/Nodes/CircleLogSoftmax.cpp
@@ -38,7 +38,7 @@ CircleNode *CircleLogSoftmaxGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleLogSoftmax>();
- node->logits(inputs[0]);
+ node->logits(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleLogicalAnd.cpp b/compiler/luci/import/src/Nodes/CircleLogicalAnd.cpp
index 8509dbaf3..7844da0f6 100644
--- a/compiler/luci/import/src/Nodes/CircleLogicalAnd.cpp
+++ b/compiler/luci/import/src/Nodes/CircleLogicalAnd.cpp
@@ -46,8 +46,8 @@ CircleNode *CircleLogicalAndGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleLogicalAnd>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleLogicalNot.cpp b/compiler/luci/import/src/Nodes/CircleLogicalNot.cpp
index b1ed3ea37..3758642e4 100644
--- a/compiler/luci/import/src/Nodes/CircleLogicalNot.cpp
+++ b/compiler/luci/import/src/Nodes/CircleLogicalNot.cpp
@@ -31,7 +31,7 @@ bool CircleLogicalNotGraphBuilder::validate(const ValidateArgs &args) const
// Only BOOL type is allowed for the input
const auto &inputs = args.op.inputs;
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
+ const auto &tensor = tensors.at(inputs.at(0));
if (tensor->type != circle::TensorType::TensorType_BOOL)
return false;
@@ -43,7 +43,7 @@ CircleNode *CircleLogicalNotGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleLogicalNot>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleLogicalOr.cpp b/compiler/luci/import/src/Nodes/CircleLogicalOr.cpp
index 00eb9c5df..1b87e6f9c 100644
--- a/compiler/luci/import/src/Nodes/CircleLogicalOr.cpp
+++ b/compiler/luci/import/src/Nodes/CircleLogicalOr.cpp
@@ -46,8 +46,8 @@ CircleNode *CircleLogicalOrGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleLogicalOr>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleLogistic.cpp b/compiler/luci/import/src/Nodes/CircleLogistic.cpp
index 85e7e55b2..9606e19cd 100644
--- a/compiler/luci/import/src/Nodes/CircleLogistic.cpp
+++ b/compiler/luci/import/src/Nodes/CircleLogistic.cpp
@@ -32,22 +32,8 @@ bool CircleLogisticGraphBuilder::validate(const ValidateArgs &args) const
if (outputs.size() != 1)
return false;
- // Must be one of the following types
- // float16, float32, float64, complex64, or complex128
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
- switch (tensor->type)
- {
- case circle::TensorType_FLOAT16:
- case circle::TensorType_FLOAT32:
- case circle::TensorType_FLOAT64:
- case circle::TensorType_COMPLEX64:
- break;
- default:
- return false;
- }
-
- if (tensors.at(inputs[0])->type != tensors.at(outputs[0])->type)
+ if (tensors.at(inputs.at(0))->type != tensors.at(outputs[0])->type)
return false;
return true;
@@ -58,7 +44,7 @@ CircleNode *CircleLogisticGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleLogistic>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleMatrixDiag.cpp b/compiler/luci/import/src/Nodes/CircleMatrixDiag.cpp
index f4ae03c58..a4a21a8b7 100644
--- a/compiler/luci/import/src/Nodes/CircleMatrixDiag.cpp
+++ b/compiler/luci/import/src/Nodes/CircleMatrixDiag.cpp
@@ -35,7 +35,7 @@ bool CircleMatrixDiagGraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
+ const auto &tensor = tensors.at(inputs.at(0));
if (tensors[outputs[0]]->type != tensor->type)
return false;
@@ -48,7 +48,7 @@ CircleNode *CircleMatrixDiagGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleMatrixDiag>();
- node->diagonal(inputs[0]);
+ node->diagonal(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleMatrixSetDiag.cpp b/compiler/luci/import/src/Nodes/CircleMatrixSetDiag.cpp
index d6f6aee33..cf0313149 100644
--- a/compiler/luci/import/src/Nodes/CircleMatrixSetDiag.cpp
+++ b/compiler/luci/import/src/Nodes/CircleMatrixSetDiag.cpp
@@ -35,7 +35,7 @@ bool CircleMatrixSetDiagGraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
+ const auto &tensor = tensors.at(inputs.at(0));
if (tensors[outputs[0]]->type != tensor->type)
return false;
@@ -48,8 +48,8 @@ CircleNode *CircleMatrixSetDiagGraphBuilder::build_node(const circle::OperatorT
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleMatrixSetDiag>();
- node->input(inputs[0]);
- node->diagonal(inputs[1]);
+ node->input(inputs.at(0));
+ node->diagonal(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleMaxPool2D.cpp b/compiler/luci/import/src/Nodes/CircleMaxPool2D.cpp
index 1798819cf..4bca0f40b 100644
--- a/compiler/luci/import/src/Nodes/CircleMaxPool2D.cpp
+++ b/compiler/luci/import/src/Nodes/CircleMaxPool2D.cpp
@@ -36,7 +36,7 @@ CircleNode *CircleMaxPool2DGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleMaxPool2D>();
- node->value(inputs[0]);
+ node->value(inputs.at(0));
const auto *options = op.builtin_options.AsPool2DOptions();
node->padding(luci_padding(options->padding));
diff --git a/compiler/luci/import/src/Nodes/CircleMaximum.cpp b/compiler/luci/import/src/Nodes/CircleMaximum.cpp
index 6ca7e4079..4d1468f19 100644
--- a/compiler/luci/import/src/Nodes/CircleMaximum.cpp
+++ b/compiler/luci/import/src/Nodes/CircleMaximum.cpp
@@ -35,7 +35,7 @@ bool CircleMaximumGraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
+ const auto &tensor = tensors.at(inputs.at(0));
switch (tensor->type)
{
@@ -49,7 +49,7 @@ bool CircleMaximumGraphBuilder::validate(const ValidateArgs &args) const
return false;
}
- if (tensors[inputs[1]]->type != tensor->type)
+ if (tensors[inputs.at(1)]->type != tensor->type)
return false;
if (tensors[outputs[0]]->type != tensor->type)
@@ -63,8 +63,8 @@ CircleNode *CircleMaximumGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleMaximum>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleMean.cpp b/compiler/luci/import/src/Nodes/CircleMean.cpp
index 8261c7b38..d8fa9a53d 100644
--- a/compiler/luci/import/src/Nodes/CircleMean.cpp
+++ b/compiler/luci/import/src/Nodes/CircleMean.cpp
@@ -34,8 +34,8 @@ CircleNode *CircleMeanGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleMean>();
- node->input(inputs[0]);
- node->reduction_indices(inputs[1]);
+ node->input(inputs.at(0));
+ node->reduction_indices(inputs.at(1));
const auto *options = op.builtin_options.AsReducerOptions();
node->keep_dims(options->keep_dims);
diff --git a/compiler/luci/import/src/Nodes/CircleMinimum.cpp b/compiler/luci/import/src/Nodes/CircleMinimum.cpp
index b770f365f..8b4daf197 100644
--- a/compiler/luci/import/src/Nodes/CircleMinimum.cpp
+++ b/compiler/luci/import/src/Nodes/CircleMinimum.cpp
@@ -35,7 +35,7 @@ bool CircleMinimumGraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
+ const auto &tensor = tensors.at(inputs.at(0));
switch (tensor->type)
{
@@ -49,7 +49,7 @@ bool CircleMinimumGraphBuilder::validate(const ValidateArgs &args) const
return false;
}
- if (tensors[inputs[1]]->type != tensor->type)
+ if (tensors[inputs.at(1)]->type != tensor->type)
return false;
if (tensors[outputs[0]]->type != tensor->type)
@@ -63,8 +63,8 @@ CircleNode *CircleMinimumGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleMinimum>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleMirrorPad.cpp b/compiler/luci/import/src/Nodes/CircleMirrorPad.cpp
index 41b5e5d80..e0ddd4c11 100644
--- a/compiler/luci/import/src/Nodes/CircleMirrorPad.cpp
+++ b/compiler/luci/import/src/Nodes/CircleMirrorPad.cpp
@@ -38,8 +38,8 @@ CircleNode *CircleMirrorPadGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleMirrorPad>();
- node->input(inputs[0]);
- node->paddings(inputs[1]);
+ node->input(inputs.at(0));
+ node->paddings(inputs.at(1));
const auto *options = op.builtin_options.AsMirrorPadOptions();
node->mode(luci_mirrorpad_mode(options->mode));
diff --git a/compiler/luci/import/src/Nodes/CircleMul.cpp b/compiler/luci/import/src/Nodes/CircleMul.cpp
index d4412b96b..e3c4a7ee5 100644
--- a/compiler/luci/import/src/Nodes/CircleMul.cpp
+++ b/compiler/luci/import/src/Nodes/CircleMul.cpp
@@ -37,8 +37,8 @@ CircleNode *CircleMulGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleMul>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
const auto *options = op.builtin_options.AsMulOptions();
node->fusedActivationFunction(luci_actfunc(options->fused_activation_function));
diff --git a/compiler/luci/import/src/Nodes/CircleNeg.cpp b/compiler/luci/import/src/Nodes/CircleNeg.cpp
index 3d3079ca2..a64a69560 100644
--- a/compiler/luci/import/src/Nodes/CircleNeg.cpp
+++ b/compiler/luci/import/src/Nodes/CircleNeg.cpp
@@ -36,7 +36,7 @@ CircleNode *CircleNegGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleNeg>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleNonMaxSuppressionV4.cpp b/compiler/luci/import/src/Nodes/CircleNonMaxSuppressionV4.cpp
new file mode 100644
index 000000000..a4ad4a53d
--- /dev/null
+++ b/compiler/luci/import/src/Nodes/CircleNonMaxSuppressionV4.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "luci/Import/Nodes/CircleNonMaxSuppressionV4.h"
+
+#include <luci/IR/Nodes/CircleNonMaxSuppressionV4.h>
+#include <luci/IR/Nodes/CircleNonMaxSuppressionV4Out.h>
+
+#include <loco.h>
+#include <oops/UserExn.h>
+
+namespace luci
+{
+
+bool CircleNonMaxSuppressionV4GraphBuilder::validate(const ValidateArgs &args) const
+{
+ const auto &inputs = args.op.inputs;
+ const auto &outputs = args.op.outputs;
+
+ if (inputs.size() != 5)
+ return false;
+ if (outputs.size() != 2)
+ return false;
+
+ const auto &tensors = args.reader.tensors();
+ const auto &boxes_tensor = tensors.at(inputs[0]);
+ if (boxes_tensor->shape.size() != 2)
+ return false;
+ if (boxes_tensor->shape.at(1) != 4)
+ return false;
+ if (boxes_tensor->shape.at(0) != tensors.at(inputs[1])->shape.at(0))
+ return false;
+
+ if (tensors.at(inputs[2])->type != circle::TensorType_INT32)
+ return false;
+ if (tensors.at(inputs[3])->type != circle::TensorType_FLOAT32)
+ return false;
+ if (tensors.at(inputs[4])->type != circle::TensorType_FLOAT32)
+ return false;
+
+ return true;
+}
+
+/**
+ * @brief NonMaxSuppressionV4 Node builder
+ *
+ * @note Current loco does not provide multiple outputs
+ * We will create multiple NonMasSuppressionV4Oout nodes to emulate this
+ */
+
+void CircleNonMaxSuppressionV4GraphBuilder::build(const circle::OperatorT &op,
+ GraphBuilderContext *context) const
+{
+ assert(context != nullptr);
+
+ auto graph = context->graph();
+
+ const std::vector<int32_t> &inputs = op.inputs;
+ const std::vector<int32_t> &outputs = op.outputs;
+ const auto &tensors = context->reader()->tensors();
+ const auto &opcodes = context->reader()->opcodes();
+ auto tensors_ptr = context->reader()->tensors_ptr();
+ assert(tensors_ptr != nullptr);
+
+ std::vector<CircleNode *> input_nodes;
+ for (const int32_t input_tensor_index : inputs)
+ {
+ input_nodes.push_back(context->nodefinder()->node(input_tensor_index));
+ }
+
+ // Create CircleNonMaxSuppressionV4
+ auto node = graph->nodes()->create<CircleNonMaxSuppressionV4>();
+ node->boxes(input_nodes[0]);
+ node->scores(input_nodes[1]);
+ node->max_output_size(input_nodes[2]);
+ node->iou_threshold(input_nodes[3]);
+ node->score_threshold(input_nodes[4]);
+
+ assert(outputs.size() == 2);
+ {
+ // Let's use name of output 0 as NonMaxSuppressionV4 name
+ const circle::TensorT &output_tensor = *tensors[outputs[0]];
+ node->name(tensor_name(output_tensor));
+ node->op_version(opcodes[op.opcode_index].get()->version);
+
+ // NOTE We don't set quantization for NonMaxSuppressionV4 itself but to virtual outputs
+ }
+
+ // Create virtual outputs of NonMaxSuppressionV4
+ for (size_t n = 0; n < outputs.size(); ++n)
+ {
+ const circle::TensorT &output_tensor = *tensors[outputs[n]];
+
+ auto *nodeout = graph->nodes()->create<CircleNonMaxSuppressionV4Out>();
+ copy_tensor_attributes(output_tensor, nodeout);
+
+ // mark shape_status
+ if (tensors_ptr->Get(outputs[n])->shape() == nullptr)
+ nodeout->shape_status(ShapeStatus::NOSHAPE);
+ else
+ nodeout->shape_status(ShapeStatus::VALID);
+
+ nodeout->input(node);
+ nodeout->index(n);
+
+ context->nodefinder()->enroll(outputs[n], nodeout);
+ }
+}
+
+} // namespace luci
diff --git a/compiler/luci/import/src/Nodes/CircleNotEqual.cpp b/compiler/luci/import/src/Nodes/CircleNotEqual.cpp
index 5b04856db..77e986de1 100644
--- a/compiler/luci/import/src/Nodes/CircleNotEqual.cpp
+++ b/compiler/luci/import/src/Nodes/CircleNotEqual.cpp
@@ -40,7 +40,7 @@ bool CircleNotEqualGraphBuilder::validate(const ValidateArgs &args) const
const auto &tensors = args.reader.tensors();
- if (tensors[inputs[0]]->type != tensors[inputs[1]]->type)
+ if (tensors[inputs.at(0)]->type != tensors[inputs.at(1)]->type)
{
return false;
}
@@ -53,8 +53,8 @@ CircleNode *CircleNotEqualGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleNotEqual>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleOneHot.cpp b/compiler/luci/import/src/Nodes/CircleOneHot.cpp
index 9fdbfa84d..69294e1ed 100644
--- a/compiler/luci/import/src/Nodes/CircleOneHot.cpp
+++ b/compiler/luci/import/src/Nodes/CircleOneHot.cpp
@@ -38,10 +38,10 @@ bool CircleOneHotGraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &indices = tensors.at(inputs[0]);
- const auto &depth = tensors.at(inputs[1]);
- const auto &on_value = tensors.at(inputs[2]);
- const auto &off_value = tensors.at(inputs[3]);
+ const auto &indices = tensors.at(inputs.at(0));
+ const auto &depth = tensors.at(inputs.at(1));
+ const auto &on_value = tensors.at(inputs.at(2));
+ const auto &off_value = tensors.at(inputs.at(3));
if (options->axis < -1 || options->axis > static_cast<int32_t>(indices->shape.size()))
return false;
@@ -63,10 +63,10 @@ CircleNode *CircleOneHotGraphBuilder::build_node(const circle::OperatorT &op,
{
auto *node = graph->nodes()->create<CircleOneHot>();
- node->indices(inputs[0]);
- node->depth(inputs[1]);
- node->on_value(inputs[2]);
- node->off_value(inputs[3]);
+ node->indices(inputs.at(0));
+ node->depth(inputs.at(1));
+ node->on_value(inputs.at(2));
+ node->off_value(inputs.at(3));
const auto *options = op.builtin_options.AsOneHotOptions();
node->axis(options->axis);
diff --git a/compiler/luci/import/src/Nodes/CirclePRelu.cpp b/compiler/luci/import/src/Nodes/CirclePRelu.cpp
index 0d87cd423..c07920f7c 100644
--- a/compiler/luci/import/src/Nodes/CirclePRelu.cpp
+++ b/compiler/luci/import/src/Nodes/CirclePRelu.cpp
@@ -39,8 +39,8 @@ CircleNode *CirclePReluGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CirclePRelu>();
- node->input(inputs[0]);
- node->alpha(inputs[1]);
+ node->input(inputs.at(0));
+ node->alpha(inputs.at(1));
// PRelu options are empty
diff --git a/compiler/luci/import/src/Nodes/CirclePad.cpp b/compiler/luci/import/src/Nodes/CirclePad.cpp
index 6abcf2d6c..999173b90 100644
--- a/compiler/luci/import/src/Nodes/CirclePad.cpp
+++ b/compiler/luci/import/src/Nodes/CirclePad.cpp
@@ -38,8 +38,8 @@ CircleNode *CirclePadGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CirclePad>();
- node->input(inputs[0]);
- node->paddings(inputs[1]);
+ node->input(inputs.at(0));
+ node->paddings(inputs.at(1));
const auto *options = op.builtin_options.AsPadOptions();
(void)options; // There are no options.
diff --git a/compiler/luci/import/src/Nodes/CirclePow.cpp b/compiler/luci/import/src/Nodes/CirclePow.cpp
index ff9833165..def012614 100644
--- a/compiler/luci/import/src/Nodes/CirclePow.cpp
+++ b/compiler/luci/import/src/Nodes/CirclePow.cpp
@@ -39,8 +39,8 @@ CircleNode *CirclePowGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CirclePow>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
// Pow options are empty
diff --git a/compiler/luci/import/src/Nodes/CircleRange.cpp b/compiler/luci/import/src/Nodes/CircleRange.cpp
index c21191605..38dc44ed6 100644
--- a/compiler/luci/import/src/Nodes/CircleRange.cpp
+++ b/compiler/luci/import/src/Nodes/CircleRange.cpp
@@ -36,9 +36,9 @@ CircleNode *CircleRangeGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleRange>();
- node->start(inputs[0]);
- node->limit(inputs[1]);
- node->delta(inputs[2]);
+ node->start(inputs.at(0));
+ node->limit(inputs.at(1));
+ node->delta(inputs.at(2));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleRank.cpp b/compiler/luci/import/src/Nodes/CircleRank.cpp
index 705ae0120..12658b192 100644
--- a/compiler/luci/import/src/Nodes/CircleRank.cpp
+++ b/compiler/luci/import/src/Nodes/CircleRank.cpp
@@ -38,7 +38,7 @@ CircleNode *CircleRankGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleRank>();
- node->input(inputs[0]);
+ node->input(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleReduceAny.cpp b/compiler/luci/import/src/Nodes/CircleReduceAny.cpp
index 030c5304c..21a821951 100644
--- a/compiler/luci/import/src/Nodes/CircleReduceAny.cpp
+++ b/compiler/luci/import/src/Nodes/CircleReduceAny.cpp
@@ -31,8 +31,8 @@ bool CircleReduceAnyGraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor_0 = tensors.at(inputs[0]);
- const auto &tensor_1 = tensors.at(inputs[1]);
+ const auto &tensor_0 = tensors.at(inputs.at(0));
+ const auto &tensor_1 = tensors.at(inputs.at(1));
const auto &tensor_o = tensors.at(outputs[0]);
if (tensor_0->type != circle::TensorType_BOOL)
@@ -57,8 +57,8 @@ CircleNode *CircleReduceAnyGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleReduceAny>();
- node->input(inputs[0]);
- node->reduction_indices(inputs[1]);
+ node->input(inputs.at(0));
+ node->reduction_indices(inputs.at(1));
const auto *options = op.builtin_options.AsReducerOptions();
node->keep_dims(options->keep_dims);
diff --git a/compiler/luci/import/src/Nodes/CircleReduceMax.cpp b/compiler/luci/import/src/Nodes/CircleReduceMax.cpp
index 8ca8e2e34..05492dbc6 100644
--- a/compiler/luci/import/src/Nodes/CircleReduceMax.cpp
+++ b/compiler/luci/import/src/Nodes/CircleReduceMax.cpp
@@ -33,7 +33,7 @@ bool CircleReduceMaxGraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor_axis = tensors.at(inputs[1]);
+ const auto &tensor_axis = tensors.at(inputs.at(1));
switch (tensor_axis->type)
{
@@ -52,8 +52,8 @@ CircleNode *CircleReduceMaxGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleReduceMax>();
- node->input(inputs[0]);
- node->reduction_indices(inputs[1]);
+ node->input(inputs.at(0));
+ node->reduction_indices(inputs.at(1));
const auto *options = op.builtin_options.AsReducerOptions();
node->keep_dims(options->keep_dims);
diff --git a/compiler/luci/import/src/Nodes/CircleReduceMin.cpp b/compiler/luci/import/src/Nodes/CircleReduceMin.cpp
index 3020c3778..117d5295a 100644
--- a/compiler/luci/import/src/Nodes/CircleReduceMin.cpp
+++ b/compiler/luci/import/src/Nodes/CircleReduceMin.cpp
@@ -33,7 +33,7 @@ bool CircleReduceMinGraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor_axis = tensors.at(inputs[1]);
+ const auto &tensor_axis = tensors.at(inputs.at(1));
switch (tensor_axis->type)
{
@@ -52,8 +52,8 @@ CircleNode *CircleReduceMinGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleReduceMin>();
- node->input(inputs[0]);
- node->reduction_indices(inputs[1]);
+ node->input(inputs.at(0));
+ node->reduction_indices(inputs.at(1));
const auto *options = op.builtin_options.AsReducerOptions();
node->keep_dims(options->keep_dims);
diff --git a/compiler/luci/import/src/Nodes/CircleReduceProd.cpp b/compiler/luci/import/src/Nodes/CircleReduceProd.cpp
index 2bb43f6ce..5f054586e 100644
--- a/compiler/luci/import/src/Nodes/CircleReduceProd.cpp
+++ b/compiler/luci/import/src/Nodes/CircleReduceProd.cpp
@@ -30,7 +30,7 @@ bool CircleReduceProdGraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor_1 = tensors.at(inputs[1]);
+ const auto &tensor_1 = tensors.at(inputs.at(1));
// TODO check input types
@@ -52,8 +52,8 @@ CircleNode *CircleReduceProdGraphBuilder::build_node(const circle::OperatorT &op
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleReduceProd>();
- node->input(inputs[0]);
- node->reduction_indices(inputs[1]);
+ node->input(inputs.at(0));
+ node->reduction_indices(inputs.at(1));
const auto *options = op.builtin_options.AsReducerOptions();
node->keep_dims(options->keep_dims);
diff --git a/compiler/luci/import/src/Nodes/CircleRelu.cpp b/compiler/luci/import/src/Nodes/CircleRelu.cpp
index 056268a5b..8e1c32a3a 100644
--- a/compiler/luci/import/src/Nodes/CircleRelu.cpp
+++ b/compiler/luci/import/src/Nodes/CircleRelu.cpp
@@ -39,7 +39,7 @@ CircleNode *CircleReluGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleRelu>();
- node->features(inputs[0]);
+ node->features(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleRelu6.cpp b/compiler/luci/import/src/Nodes/CircleRelu6.cpp
index 5b443993b..0283d7350 100644
--- a/compiler/luci/import/src/Nodes/CircleRelu6.cpp
+++ b/compiler/luci/import/src/Nodes/CircleRelu6.cpp
@@ -39,7 +39,7 @@ CircleNode *CircleRelu6GraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleRelu6>();
- node->features(inputs[0]);
+ node->features(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleReluN1To1.cpp b/compiler/luci/import/src/Nodes/CircleReluN1To1.cpp
index edf662fb9..7f517bc0d 100644
--- a/compiler/luci/import/src/Nodes/CircleReluN1To1.cpp
+++ b/compiler/luci/import/src/Nodes/CircleReluN1To1.cpp
@@ -41,7 +41,7 @@ CircleNode *CircleReluN1To1GraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleReluN1To1>();
- node->features(inputs[0]);
+ node->features(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleReshape.cpp b/compiler/luci/import/src/Nodes/CircleReshape.cpp
index f72c152b1..996ae9d20 100644
--- a/compiler/luci/import/src/Nodes/CircleReshape.cpp
+++ b/compiler/luci/import/src/Nodes/CircleReshape.cpp
@@ -62,7 +62,7 @@ CircleNode *CircleReshapeGraphBuilder::build_node(const circle::OperatorT &op,
{
// If the second input is not provided, generate it based on the value of the attribute.
// TODO Presence of the second input is the current requirement of the IR.
- auto *shape_node = (inputs.size() == 2) ? inputs[1] : nullptr;
+ auto *shape_node = (inputs.size() == 2) ? inputs.at(1) : nullptr;
if (shape_node == nullptr)
{
const auto *options = op.builtin_options.AsReshapeOptions();
@@ -77,7 +77,7 @@ CircleNode *CircleReshapeGraphBuilder::build_node(const circle::OperatorT &op,
}
auto *node = graph->nodes()->create<CircleReshape>();
- node->tensor(inputs[0]);
+ node->tensor(inputs.at(0));
node->shape(shape_node);
const auto *options = op.builtin_options.AsReshapeOptions();
diff --git a/compiler/luci/import/src/Nodes/CircleResizeBilinear.cpp b/compiler/luci/import/src/Nodes/CircleResizeBilinear.cpp
index 6128f1b86..0fccb7b44 100644
--- a/compiler/luci/import/src/Nodes/CircleResizeBilinear.cpp
+++ b/compiler/luci/import/src/Nodes/CircleResizeBilinear.cpp
@@ -38,8 +38,8 @@ CircleNode *CircleResizeBilinearGraphBuilder::build_node(const circle::OperatorT
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleResizeBilinear>();
- node->input(inputs[0]);
- node->size(inputs[1]);
+ node->input(inputs.at(0));
+ node->size(inputs.at(1));
const auto *options = op.builtin_options.AsResizeBilinearOptions();
node->align_corners(options->align_corners);
diff --git a/compiler/luci/import/src/Nodes/CircleResizeNearestNeighbor.cpp b/compiler/luci/import/src/Nodes/CircleResizeNearestNeighbor.cpp
index a1f1ef0ff..324323f59 100644
--- a/compiler/luci/import/src/Nodes/CircleResizeNearestNeighbor.cpp
+++ b/compiler/luci/import/src/Nodes/CircleResizeNearestNeighbor.cpp
@@ -37,8 +37,8 @@ CircleNode *CircleResizeNearestNeighborGraphBuilder::build_node(
const circle::OperatorT &op, const std::vector<CircleNode *> &inputs, loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleResizeNearestNeighbor>();
- node->input(inputs[0]);
- node->size(inputs[1]);
+ node->input(inputs.at(0));
+ node->size(inputs.at(1));
const auto *options = op.builtin_options.AsResizeNearestNeighborOptions();
node->align_corners(options->align_corners);
diff --git a/compiler/luci/import/src/Nodes/CircleReverseSequence.cpp b/compiler/luci/import/src/Nodes/CircleReverseSequence.cpp
index 72d3b153d..ad11d4c63 100644
--- a/compiler/luci/import/src/Nodes/CircleReverseSequence.cpp
+++ b/compiler/luci/import/src/Nodes/CircleReverseSequence.cpp
@@ -34,8 +34,8 @@ bool CircleReverseSequenceGraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor_in = tensors.at(inputs[0]);
- const auto &tensor_lengths = tensors.at(inputs[1]);
+ const auto &tensor_in = tensors.at(inputs.at(0));
+ const auto &tensor_lengths = tensors.at(inputs.at(1));
const auto &tensor_out = tensors.at(outputs[0]);
switch (tensor_lengths->type)
@@ -58,8 +58,8 @@ CircleNode *CircleReverseSequenceGraphBuilder::build_node(const circle::Operator
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleReverseSequence>();
- node->input(inputs[0]);
- node->seq_lengths(inputs[1]);
+ node->input(inputs.at(0));
+ node->seq_lengths(inputs.at(1));
const auto *options = op.builtin_options.AsReverseSequenceOptions();
node->seq_axis(options->seq_dim);
diff --git a/compiler/luci/import/src/Nodes/CircleReverseV2.cpp b/compiler/luci/import/src/Nodes/CircleReverseV2.cpp
index cd18128a7..e2e53bb4b 100644
--- a/compiler/luci/import/src/Nodes/CircleReverseV2.cpp
+++ b/compiler/luci/import/src/Nodes/CircleReverseV2.cpp
@@ -34,8 +34,8 @@ bool CircleReverseV2GraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor_in = tensors.at(inputs[0]);
- const auto &tensor_axis = tensors.at(inputs[1]);
+ const auto &tensor_in = tensors.at(inputs.at(0));
+ const auto &tensor_axis = tensors.at(inputs.at(1));
const auto &tensor_out = tensors.at(outputs[0]);
switch (tensor_axis->type)
@@ -58,8 +58,8 @@ CircleNode *CircleReverseV2GraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleReverseV2>();
- node->tensor(inputs[0]);
- node->axis(inputs[1]);
+ node->tensor(inputs.at(0));
+ node->axis(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleRound.cpp b/compiler/luci/import/src/Nodes/CircleRound.cpp
index 896489521..ad77f9f03 100644
--- a/compiler/luci/import/src/Nodes/CircleRound.cpp
+++ b/compiler/luci/import/src/Nodes/CircleRound.cpp
@@ -37,7 +37,7 @@ bool CircleRoundGraphBuilder::validate(const ValidateArgs &args) const
// bfloat16, half (float16), float32, float64, complex64, complex128
// Currently, circle supports float16, float32, complex64
const auto &tensors = args.reader.tensors();
- const auto &tensor_in = tensors.at(inputs[0]);
+ const auto &tensor_in = tensors.at(inputs.at(0));
const auto &tensor_out = tensors.at(outputs[0]);
switch (tensor_in->type)
@@ -63,7 +63,7 @@ CircleNode *CircleRoundGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleRound>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleRsqrt.cpp b/compiler/luci/import/src/Nodes/CircleRsqrt.cpp
index b5de0b575..ae05fbbf9 100644
--- a/compiler/luci/import/src/Nodes/CircleRsqrt.cpp
+++ b/compiler/luci/import/src/Nodes/CircleRsqrt.cpp
@@ -33,7 +33,7 @@ bool CircleRsqrtGraphBuilder::validate(const ValidateArgs &args) const
// bfloat16, half (float16), float32, float64, complex64, complex128
// Currently, circle supports float16, float32, complex64
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
+ const auto &tensor = tensors.at(inputs.at(0));
switch (tensor->type)
{
case circle::TensorType_FLOAT16:
@@ -52,7 +52,7 @@ CircleNode *CircleRsqrtGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleRsqrt>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleScatterNd.cpp b/compiler/luci/import/src/Nodes/CircleScatterNd.cpp
index adcaa0030..7f86aeb74 100644
--- a/compiler/luci/import/src/Nodes/CircleScatterNd.cpp
+++ b/compiler/luci/import/src/Nodes/CircleScatterNd.cpp
@@ -32,12 +32,12 @@ bool CircleScatterNdGraphBuilder::validate(const ValidateArgs &args) const
// indices must have the same type as shape
const auto &tensors = args.reader.tensors();
- if (tensors[inputs[0]]->type != tensors[inputs[2]]->type)
+ if (tensors[inputs.at(0)]->type != tensors[inputs.at(2)]->type)
return false;
// indices must be either int32 or int64
- if (tensors[inputs[0]]->type != circle::TensorType_INT32 &&
- tensors[inputs[0]]->type != circle::TensorType_INT64)
+ if (tensors[inputs.at(0)]->type != circle::TensorType_INT32 &&
+ tensors[inputs.at(0)]->type != circle::TensorType_INT64)
return false;
return true;
@@ -48,9 +48,9 @@ CircleNode *CircleScatterNdGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleScatterNd>();
- node->indices(inputs[0]);
- node->updates(inputs[1]);
- node->shape(inputs[2]);
+ node->indices(inputs.at(0));
+ node->updates(inputs.at(1));
+ node->shape(inputs.at(2));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleSegmentSum.cpp b/compiler/luci/import/src/Nodes/CircleSegmentSum.cpp
index 1122bdca3..fb84e5d52 100644
--- a/compiler/luci/import/src/Nodes/CircleSegmentSum.cpp
+++ b/compiler/luci/import/src/Nodes/CircleSegmentSum.cpp
@@ -33,9 +33,9 @@ bool CircleSegmentSumGraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor_in = tensors.at(inputs[0]);
+ const auto &tensor_in = tensors.at(inputs.at(0));
const auto &tensor_out = tensors.at(outputs[0]);
- const auto &tensor_ids = tensors.at(inputs[1]);
+ const auto &tensor_ids = tensors.at(inputs.at(1));
switch (tensor_ids->type)
{
@@ -59,8 +59,8 @@ CircleNode *CircleSegmentSumGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleSegmentSum>();
- node->input(inputs[0]);
- node->segment_ids(inputs[1]);
+ node->input(inputs.at(0));
+ node->segment_ids(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleSelect.cpp b/compiler/luci/import/src/Nodes/CircleSelect.cpp
index ff94212c3..1e649f1e0 100644
--- a/compiler/luci/import/src/Nodes/CircleSelect.cpp
+++ b/compiler/luci/import/src/Nodes/CircleSelect.cpp
@@ -33,7 +33,7 @@ bool CircleSelectGraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
+ const auto &tensor = tensors.at(inputs.at(0));
if (tensor->type != circle::TensorType_BOOL)
return false;
// TODO check dtypes for input 1, 2
@@ -46,9 +46,9 @@ CircleNode *CircleSelectGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleSelect>();
- node->condition(inputs[0]);
- node->t(inputs[1]);
- node->e(inputs[2]);
+ node->condition(inputs.at(0));
+ node->t(inputs.at(1));
+ node->e(inputs.at(2));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleSelectV2.cpp b/compiler/luci/import/src/Nodes/CircleSelectV2.cpp
index 78b2e6459..e6dd04de0 100644
--- a/compiler/luci/import/src/Nodes/CircleSelectV2.cpp
+++ b/compiler/luci/import/src/Nodes/CircleSelectV2.cpp
@@ -33,12 +33,12 @@ bool CircleSelectV2GraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &condition = tensors.at(inputs[0]);
+ const auto &condition = tensors.at(inputs.at(0));
if (condition->type != circle::TensorType_BOOL)
return false;
- const auto &t = tensors.at(inputs[1]);
- const auto &e = tensors.at(inputs[2]);
+ const auto &t = tensors.at(inputs.at(1));
+ const auto &e = tensors.at(inputs.at(2));
if (t->type != e->type)
return false;
@@ -50,9 +50,9 @@ CircleNode *CircleSelectV2GraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleSelectV2>();
- node->condition(inputs[0]);
- node->t(inputs[1]);
- node->e(inputs[2]);
+ node->condition(inputs.at(0));
+ node->t(inputs.at(1));
+ node->e(inputs.at(2));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleShape.cpp b/compiler/luci/import/src/Nodes/CircleShape.cpp
index 864b5eb51..bd7dfc9d9 100644
--- a/compiler/luci/import/src/Nodes/CircleShape.cpp
+++ b/compiler/luci/import/src/Nodes/CircleShape.cpp
@@ -42,7 +42,7 @@ CircleNode *CircleShapeGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleShape>();
- node->input(inputs[0]);
+ node->input(inputs.at(0));
const auto *options = op.builtin_options.AsShapeOptions();
node->out_type(luci_datatype(options->out_type));
diff --git a/compiler/luci/import/src/Nodes/CircleSin.cpp b/compiler/luci/import/src/Nodes/CircleSin.cpp
index 61d60c78f..4b245ef6b 100644
--- a/compiler/luci/import/src/Nodes/CircleSin.cpp
+++ b/compiler/luci/import/src/Nodes/CircleSin.cpp
@@ -33,7 +33,7 @@ bool CircleSinGraphBuilder::validate(const ValidateArgs &args) const
// input type check
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
+ const auto &tensor = tensors.at(inputs.at(0));
switch (tensor->type)
{
case circle::TensorType_FLOAT16:
@@ -53,7 +53,7 @@ CircleNode *CircleSinGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleSin>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
// No options for Sin
diff --git a/compiler/luci/import/src/Nodes/CircleSlice.cpp b/compiler/luci/import/src/Nodes/CircleSlice.cpp
index 313c35599..8601fbf21 100644
--- a/compiler/luci/import/src/Nodes/CircleSlice.cpp
+++ b/compiler/luci/import/src/Nodes/CircleSlice.cpp
@@ -42,9 +42,9 @@ CircleNode *CircleSliceGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleSlice>();
- node->input(inputs[0]);
- node->begin(inputs[1]);
- node->size(inputs[2]);
+ node->input(inputs.at(0));
+ node->begin(inputs.at(1));
+ node->size(inputs.at(2));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleSoftmax.cpp b/compiler/luci/import/src/Nodes/CircleSoftmax.cpp
index 0d316e18c..0ef0b5418 100644
--- a/compiler/luci/import/src/Nodes/CircleSoftmax.cpp
+++ b/compiler/luci/import/src/Nodes/CircleSoftmax.cpp
@@ -38,7 +38,7 @@ CircleNode *CircleSoftmaxGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleSoftmax>();
- node->logits(inputs[0]);
+ node->logits(inputs.at(0));
const auto *options = op.builtin_options.AsSoftmaxOptions();
node->beta(options->beta);
diff --git a/compiler/luci/import/src/Nodes/CircleSpaceToBatchND.cpp b/compiler/luci/import/src/Nodes/CircleSpaceToBatchND.cpp
index f1361fb11..c1d508e3e 100644
--- a/compiler/luci/import/src/Nodes/CircleSpaceToBatchND.cpp
+++ b/compiler/luci/import/src/Nodes/CircleSpaceToBatchND.cpp
@@ -33,7 +33,7 @@ bool CircleSpaceToBatchNDGraphBuilder::validate(const ValidateArgs &args) const
// input 1 and 2 should have INT32/INT64 type
const auto &tensors = args.reader.tensors();
- const auto &tensor_1 = tensors.at(inputs[1]);
+ const auto &tensor_1 = tensors.at(inputs.at(1));
switch (tensor_1->type)
{
case circle::TensorType_INT32:
@@ -42,7 +42,7 @@ bool CircleSpaceToBatchNDGraphBuilder::validate(const ValidateArgs &args) const
default:
return false;
}
- const auto &tensor_2 = tensors.at(inputs[2]);
+ const auto &tensor_2 = tensors.at(inputs.at(2));
switch (tensor_2->type)
{
case circle::TensorType_INT32:
@@ -53,7 +53,7 @@ bool CircleSpaceToBatchNDGraphBuilder::validate(const ValidateArgs &args) const
}
// Only support input shape dimension 3 and 4 only
- const auto &tensor_0 = tensors.at(inputs[0]);
+ const auto &tensor_0 = tensors.at(inputs.at(0));
const auto t_0_s = tensor_0->shape.size();
if (t_0_s != 3 && t_0_s != 4)
return false;
@@ -68,9 +68,9 @@ CircleNode *CircleSpaceToBatchNDGraphBuilder::build_node(const circle::OperatorT
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleSpaceToBatchND>();
- node->input(inputs[0]);
- node->block_shape(inputs[1]);
- node->paddings(inputs[2]);
+ node->input(inputs.at(0));
+ node->block_shape(inputs.at(1));
+ node->paddings(inputs.at(2));
// No options for SpaceToBatchND
diff --git a/compiler/luci/import/src/Nodes/CircleSpaceToDepth.cpp b/compiler/luci/import/src/Nodes/CircleSpaceToDepth.cpp
index b612c9a9a..8ccd55dc6 100644
--- a/compiler/luci/import/src/Nodes/CircleSpaceToDepth.cpp
+++ b/compiler/luci/import/src/Nodes/CircleSpaceToDepth.cpp
@@ -41,7 +41,7 @@ CircleNode *CircleSpaceToDepthGraphBuilder::build_node(const circle::OperatorT &
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleSpaceToDepth>();
- node->input(inputs[0]);
+ node->input(inputs.at(0));
const auto *options = op.builtin_options.AsSpaceToDepthOptions();
node->block_size(options->block_size);
diff --git a/compiler/luci/import/src/Nodes/CircleSparseToDense.cpp b/compiler/luci/import/src/Nodes/CircleSparseToDense.cpp
index bfe790fc1..26d575e90 100644
--- a/compiler/luci/import/src/Nodes/CircleSparseToDense.cpp
+++ b/compiler/luci/import/src/Nodes/CircleSparseToDense.cpp
@@ -36,10 +36,10 @@ CircleNode *CircleSparseToDenseGraphBuilder::build_node(const circle::OperatorT
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleSparseToDense>();
- node->indices(inputs[0]);
- node->output_shape(inputs[1]);
- node->values(inputs[2]);
- node->default_value(inputs[3]);
+ node->indices(inputs.at(0));
+ node->output_shape(inputs.at(1));
+ node->values(inputs.at(2));
+ node->default_value(inputs.at(3));
const auto *options = op.builtin_options.AsSparseToDenseOptions();
node->validate_indices(options->validate_indices);
diff --git a/compiler/luci/import/src/Nodes/CircleSqrt.cpp b/compiler/luci/import/src/Nodes/CircleSqrt.cpp
index 8a90f6691..c8beaee0d 100644
--- a/compiler/luci/import/src/Nodes/CircleSqrt.cpp
+++ b/compiler/luci/import/src/Nodes/CircleSqrt.cpp
@@ -36,7 +36,7 @@ CircleNode *CircleSqrtGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleSqrt>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleSquare.cpp b/compiler/luci/import/src/Nodes/CircleSquare.cpp
index 8398548b6..b5ba048d7 100644
--- a/compiler/luci/import/src/Nodes/CircleSquare.cpp
+++ b/compiler/luci/import/src/Nodes/CircleSquare.cpp
@@ -33,7 +33,7 @@ bool CircleSquareGraphBuilder::validate(const ValidateArgs &args) const
// bfloat16, half (float16), float32, float64, complex64, complex128
// Currently, circle supports float16, float32, complex64
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
+ const auto &tensor = tensors.at(inputs.at(0));
switch (tensor->type)
{
case circle::TensorType_INT32:
@@ -55,7 +55,7 @@ CircleNode *CircleSquareGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleSquare>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleSquaredDifference.cpp b/compiler/luci/import/src/Nodes/CircleSquaredDifference.cpp
index 93ce959e2..6deae94c5 100644
--- a/compiler/luci/import/src/Nodes/CircleSquaredDifference.cpp
+++ b/compiler/luci/import/src/Nodes/CircleSquaredDifference.cpp
@@ -37,7 +37,7 @@ bool CircleSquaredDifferenceGraphBuilder::validate(const ValidateArgs &args) con
// Inputs must be one of the following types
// bfloat16, half(float16), float32, float64, int32, int64, complex64, complex128
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
+ const auto &tensor = tensors.at(inputs.at(0));
switch (tensor->type)
{
case circle::TensorType_FLOAT16:
@@ -53,11 +53,11 @@ bool CircleSquaredDifferenceGraphBuilder::validate(const ValidateArgs &args) con
}
// Input types must match
- if (tensors.at(inputs[0])->type != tensors.at(inputs[1])->type)
+ if (tensors.at(inputs.at(0))->type != tensors.at(inputs.at(1))->type)
return false;
// Input and output types must match
- if (tensors.at(inputs[0])->type != tensors.at(outputs[0])->type)
+ if (tensors.at(inputs.at(0))->type != tensors.at(outputs[0])->type)
return false;
return true;
@@ -68,8 +68,8 @@ CircleNode *CircleSquaredDifferenceGraphBuilder::build_node(const circle::Operat
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleSquaredDifference>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleSqueeze.cpp b/compiler/luci/import/src/Nodes/CircleSqueeze.cpp
index a5252d0bb..32792c266 100644
--- a/compiler/luci/import/src/Nodes/CircleSqueeze.cpp
+++ b/compiler/luci/import/src/Nodes/CircleSqueeze.cpp
@@ -38,7 +38,7 @@ CircleNode *CircleSqueezeGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleSqueeze>();
- node->input(inputs[0]);
+ node->input(inputs.at(0));
const auto *options = op.builtin_options.AsSqueezeOptions();
assert(options);
diff --git a/compiler/luci/import/src/Nodes/CircleStridedSlice.cpp b/compiler/luci/import/src/Nodes/CircleStridedSlice.cpp
index 95e446704..8f943a682 100644
--- a/compiler/luci/import/src/Nodes/CircleStridedSlice.cpp
+++ b/compiler/luci/import/src/Nodes/CircleStridedSlice.cpp
@@ -42,10 +42,10 @@ CircleNode *CircleStridedSliceGraphBuilder::build_node(const circle::OperatorT &
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleStridedSlice>();
- node->input(inputs[0]);
- node->begin(inputs[1]);
- node->end(inputs[2]);
- node->strides(inputs[3]);
+ node->input(inputs.at(0));
+ node->begin(inputs.at(1));
+ node->end(inputs.at(2));
+ node->strides(inputs.at(3));
const auto *options = op.builtin_options.AsStridedSliceOptions();
node->begin_mask(options->begin_mask);
diff --git a/compiler/luci/import/src/Nodes/CircleSub.cpp b/compiler/luci/import/src/Nodes/CircleSub.cpp
index 968e9f51f..9acf83d40 100644
--- a/compiler/luci/import/src/Nodes/CircleSub.cpp
+++ b/compiler/luci/import/src/Nodes/CircleSub.cpp
@@ -39,8 +39,8 @@ CircleNode *CircleSubGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleSub>();
- node->x(inputs[0]);
- node->y(inputs[1]);
+ node->x(inputs.at(0));
+ node->y(inputs.at(1));
const auto *options = op.builtin_options.AsSubOptions();
node->fusedActivationFunction(luci_actfunc(options->fused_activation_function));
diff --git a/compiler/luci/import/src/Nodes/CircleSum.cpp b/compiler/luci/import/src/Nodes/CircleSum.cpp
index b4865de59..bd3cb6239 100644
--- a/compiler/luci/import/src/Nodes/CircleSum.cpp
+++ b/compiler/luci/import/src/Nodes/CircleSum.cpp
@@ -34,8 +34,8 @@ CircleNode *CircleSumGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleSum>();
- node->input(inputs[0]);
- node->reduction_indices(inputs[1]);
+ node->input(inputs.at(0));
+ node->reduction_indices(inputs.at(1));
const auto *options = op.builtin_options.AsReducerOptions();
node->keep_dims(options->keep_dims);
diff --git a/compiler/luci/import/src/Nodes/CircleTanh.cpp b/compiler/luci/import/src/Nodes/CircleTanh.cpp
index 8986378c4..018f5701b 100644
--- a/compiler/luci/import/src/Nodes/CircleTanh.cpp
+++ b/compiler/luci/import/src/Nodes/CircleTanh.cpp
@@ -28,21 +28,13 @@ bool CircleTanhGraphBuilder::validate(const ValidateArgs &args) const
const auto &inputs = args.op.inputs;
if (inputs.size() != 1)
return false;
+ const auto &outputs = args.op.outputs;
+ if (outputs.size() != 1)
+ return false;
- // Must be one of the following types
- // bfloat16, half (float16), float32, float64, complex64, complex128
- // Currently, circle supports float16, float32, complex64
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
- switch (tensor->type)
- {
- case circle::TensorType_FLOAT16:
- case circle::TensorType_FLOAT32:
- case circle::TensorType_COMPLEX64:
- break;
- default:
- return false;
- }
+ if (tensors.at(inputs.at(0))->type != tensors.at(outputs[0])->type)
+ return false;
return true;
}
@@ -52,7 +44,7 @@ CircleNode *CircleTanhGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleTanh>();
- node->x(inputs[0]);
+ node->x(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleTile.cpp b/compiler/luci/import/src/Nodes/CircleTile.cpp
index 91054ce7f..bc6f320ba 100644
--- a/compiler/luci/import/src/Nodes/CircleTile.cpp
+++ b/compiler/luci/import/src/Nodes/CircleTile.cpp
@@ -34,10 +34,10 @@ bool CircleTileGraphBuilder::validate(const ValidateArgs &args) const
if (outputs.size() != 1)
return false;
- // Multiples (inputs[1]) must be one of the following types
+ // Multiples (inputs.at(1)) must be one of the following types
// int32, int64
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[1]);
+ const auto &tensor = tensors.at(inputs.at(1));
switch (tensor->type)
{
case circle::TensorType_INT32:
@@ -48,7 +48,7 @@ bool CircleTileGraphBuilder::validate(const ValidateArgs &args) const
}
// Type of input and output must be the same
- if (tensors.at(inputs[0])->type != tensors.at(outputs[0])->type)
+ if (tensors.at(inputs.at(0))->type != tensors.at(outputs[0])->type)
return false;
return true;
@@ -59,8 +59,8 @@ CircleNode *CircleTileGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleTile>();
- node->input(inputs[0]);
- node->multiples(inputs[1]);
+ node->input(inputs.at(0));
+ node->multiples(inputs.at(1));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleTopKV2.cpp b/compiler/luci/import/src/Nodes/CircleTopKV2.cpp
index 5c1051c43..f0677de86 100644
--- a/compiler/luci/import/src/Nodes/CircleTopKV2.cpp
+++ b/compiler/luci/import/src/Nodes/CircleTopKV2.cpp
@@ -36,7 +36,7 @@ bool CircleTopKV2GraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[1]);
+ const auto &tensor = tensors.at(inputs.at(1));
if (tensor->type != circle::TensorType_INT32)
return false;
diff --git a/compiler/luci/import/src/Nodes/CircleTranspose.cpp b/compiler/luci/import/src/Nodes/CircleTranspose.cpp
index 8622c8b80..cc3153085 100644
--- a/compiler/luci/import/src/Nodes/CircleTranspose.cpp
+++ b/compiler/luci/import/src/Nodes/CircleTranspose.cpp
@@ -39,8 +39,8 @@ CircleNode *CircleTransposeGraphBuilder::build_node(const circle::OperatorT &op,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleTranspose>();
- node->a(inputs[0]);
- node->perm(inputs[1]);
+ node->a(inputs.at(0));
+ node->perm(inputs.at(1));
const auto *options = op.builtin_options.AsTransposeOptions();
(void)options;
diff --git a/compiler/luci/import/src/Nodes/CircleTransposeConv.cpp b/compiler/luci/import/src/Nodes/CircleTransposeConv.cpp
index 7bdf46daa..ddb196657 100644
--- a/compiler/luci/import/src/Nodes/CircleTransposeConv.cpp
+++ b/compiler/luci/import/src/Nodes/CircleTransposeConv.cpp
@@ -30,6 +30,24 @@ bool CircleTransposeConvGraphBuilder::validate(const ValidateArgs &args) const
if (args.op.inputs.size() != 3)
return false;
+ const auto &inputs = args.op.inputs;
+ const auto &tensors = args.reader.tensors();
+ const auto &filter_tensor = tensors.at(inputs.at(1));
+ const auto &filter_shape = filter_tensor.get()->shape;
+ const auto &ifm_tensor = tensors.at(inputs.at(2));
+ const auto &ifm_shape = ifm_tensor.get()->shape;
+
+ // ifm and filters must be 4-D tensor
+ if (ifm_shape.size() != 4)
+ return false;
+ if (filter_shape.size() != 4)
+ return false;
+
+ // input shape : [batch, height, width, in_channels]
+ // filters shape : [output_channels, height, weight, in_channels]
+ if (ifm_tensor.get()->shape.at(3) != filter_tensor.get()->shape.at(3))
+ return false;
+
return true;
}
@@ -39,9 +57,9 @@ CircleNode *CircleTransposeConvGraphBuilder::build_node(const circle::OperatorT
{
auto *node = graph->nodes()->create<CircleTransposeConv>();
- node->inputSizes(inputs[0]);
- node->filter(inputs[1]);
- node->outBackprop(inputs[2]);
+ node->inputSizes(inputs.at(0));
+ node->filter(inputs.at(1));
+ node->outBackprop(inputs.at(2));
const auto *options = op.builtin_options.AsTransposeConvOptions();
node->padding(luci_padding(options->padding));
diff --git a/compiler/luci/import/src/Nodes/CircleUnique.cpp b/compiler/luci/import/src/Nodes/CircleUnique.cpp
new file mode 100644
index 000000000..5e79a2920
--- /dev/null
+++ b/compiler/luci/import/src/Nodes/CircleUnique.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "luci/Import/Nodes/CircleUnique.h"
+
+#include <luci/IR/Nodes/CircleUnique.h>
+#include <luci/IR/Nodes/CircleUniqueOut.h>
+
+#include <loco.h>
+
+namespace luci
+{
+
+bool CircleUniqueGraphBuilder::validate(const ValidateArgs &args) const
+{
+ if (args.op.inputs.size() != 1)
+ return false;
+
+ if (args.op.outputs.size() != 2)
+ return false;
+
+ return true;
+}
+
+void CircleUniqueGraphBuilder::build(const circle::OperatorT &op,
+ GraphBuilderContext *context) const
+{
+ assert(context != nullptr);
+
+ auto graph = context->graph();
+
+ const std::vector<int32_t> &inputs = op.inputs;
+ const std::vector<int32_t> &outputs = op.outputs;
+ const auto &tensors = context->reader()->tensors();
+ auto tensors_ptr = context->reader()->tensors_ptr();
+ assert(tensors_ptr != nullptr);
+
+ std::vector<CircleNode *> input_nodes;
+ for (const int32_t input_tensor_index : inputs)
+ {
+ input_nodes.push_back(context->nodefinder()->node(input_tensor_index));
+ }
+
+ // Create CircleUnique
+ auto node = graph->nodes()->create<CircleUnique>();
+ node->input(input_nodes[0]);
+
+ const auto *options = op.builtin_options.AsUniqueOptions();
+ node->output_type(luci_datatype(options->idx_out_type));
+
+ assert(int32_t(outputs.size()) == 2);
+ // Let's use name of output 0 as Unique name
+ const circle::TensorT &output_tensor = *tensors[outputs[0]];
+ node->name(tensor_name(output_tensor));
+
+ // Create virtual outputs of Unique
+ for (int32_t n = 0; n < 2; ++n)
+ {
+ const circle::TensorT &output_tensor = *tensors[outputs[n]];
+
+ auto *nodeout = graph->nodes()->create<CircleUniqueOut>();
+ copy_tensor_attributes(output_tensor, nodeout);
+ // mark shape_status
+ if (tensors_ptr->Get(outputs[n])->shape() == nullptr)
+ nodeout->shape_status(ShapeStatus::NOSHAPE);
+ else
+ nodeout->shape_status(ShapeStatus::VALID);
+
+ nodeout->input(node);
+ nodeout->index(n);
+
+ context->nodefinder()->enroll(outputs[n], nodeout);
+ }
+}
+
+} // namespace luci
diff --git a/compiler/luci/import/src/Nodes/CircleUnpack.cpp b/compiler/luci/import/src/Nodes/CircleUnpack.cpp
index c4282e24f..9e7f3d3e1 100644
--- a/compiler/luci/import/src/Nodes/CircleUnpack.cpp
+++ b/compiler/luci/import/src/Nodes/CircleUnpack.cpp
@@ -59,7 +59,7 @@ bool CircleUnpackGraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor = tensors.at(inputs[0]);
+ const auto &tensor = tensors.at(inputs.at(0));
const auto &shape = tensor->shape;
auto shape_size = static_cast<int32_t>(shape.size());
if (shape_size > 0)
diff --git a/compiler/luci/import/src/Nodes/CircleWhere.cpp b/compiler/luci/import/src/Nodes/CircleWhere.cpp
index a13c4d6c9..f4c5f0c66 100644
--- a/compiler/luci/import/src/Nodes/CircleWhere.cpp
+++ b/compiler/luci/import/src/Nodes/CircleWhere.cpp
@@ -35,7 +35,7 @@ bool CircleWhereGraphBuilder::validate(const ValidateArgs &args) const
return false;
const auto &tensors = args.reader.tensors();
- const auto &tensor_condition = tensors.at(inputs[0]);
+ const auto &tensor_condition = tensors.at(inputs.at(0));
const auto &tensor_out = tensors.at(outputs[0]);
if (tensor_condition->type != circle::TensorType_BOOL)
@@ -52,7 +52,7 @@ CircleNode *CircleWhereGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleWhere>();
- node->condition(inputs[0]);
+ node->condition(inputs.at(0));
return node;
}
diff --git a/compiler/luci/import/src/Nodes/CircleZerosLike.cpp b/compiler/luci/import/src/Nodes/CircleZerosLike.cpp
index 4362925cd..e60424def 100644
--- a/compiler/luci/import/src/Nodes/CircleZerosLike.cpp
+++ b/compiler/luci/import/src/Nodes/CircleZerosLike.cpp
@@ -39,7 +39,7 @@ CircleNode *CircleZerosLikeGraphBuilder::build_node(const circle::OperatorT &,
loco::Graph *graph) const
{
auto *node = graph->nodes()->create<CircleZerosLike>();
- node->input(inputs[0]);
+ node->input(inputs.at(0));
// ZerosLikeOptinos are empty
diff --git a/compiler/luci/lang/include/luci/IR/CircleNodes.h b/compiler/luci/lang/include/luci/IR/CircleNodes.h
index 3b31149b2..e57f5bb3e 100644
--- a/compiler/luci/lang/include/luci/IR/CircleNodes.h
+++ b/compiler/luci/lang/include/luci/IR/CircleNodes.h
@@ -70,10 +70,12 @@
#include "Nodes/CircleMirrorPad.h"
#include "Nodes/CircleMul.h"
#include "Nodes/CircleNeg.h"
+#include "Nodes/CircleNonMaxSuppressionV4.h"
#include "Nodes/CircleNotEqual.h"
#include "Nodes/CircleOneHot.h"
#include "Nodes/CirclePack.h"
#include "Nodes/CirclePad.h"
+#include "Nodes/CirclePadV2.h"
#include "Nodes/CirclePow.h"
#include "Nodes/CirclePRelu.h"
#include "Nodes/CircleRange.h"
@@ -117,6 +119,7 @@
#include "Nodes/CircleTopKV2.h"
#include "Nodes/CircleTranspose.h"
#include "Nodes/CircleTransposeConv.h"
+#include "Nodes/CircleUnique.h"
#include "Nodes/CircleUnpack.h"
#include "Nodes/CircleWhere.h"
#include "Nodes/CircleWhile.h"
@@ -130,7 +133,9 @@
#include "Nodes/CircleOutput.h"
#include "Nodes/CircleCustomOut.h"
#include "Nodes/CircleIfOut.h"
+#include "Nodes/CircleNonMaxSuppressionV4Out.h"
#include "Nodes/CircleUnpackOut.h"
+#include "Nodes/CircleUniqueOut.h"
#include "Nodes/CircleSplitOut.h"
#include "Nodes/CircleSplitVOut.h"
#include "Nodes/CircleTopKV2Out.h"
diff --git a/compiler/luci/lang/include/luci/IR/CircleNodes.lst b/compiler/luci/lang/include/luci/IR/CircleNodes.lst
index 488dcfb89..801051848 100644
--- a/compiler/luci/lang/include/luci/IR/CircleNodes.lst
+++ b/compiler/luci/lang/include/luci/IR/CircleNodes.lst
@@ -22,7 +22,6 @@ CIRCLE_NODE(BATCHMATMUL, luci::CircleBatchMatMul)
CIRCLE_NODE(CAST, luci::CircleCast)
CIRCLE_NODE(CEIL, luci::CircleCeil)
CIRCLE_NODE(CONCATENATION, luci::CircleConcatenation)
-CIRCLE_NODE(CONST, luci::CircleConst)
CIRCLE_NODE(CONV_2D, luci::CircleConv2D)
CIRCLE_NODE(COS, luci::CircleCos)
CIRCLE_NODE(CUSTOM, luci::CircleCustom)
@@ -64,10 +63,12 @@ CIRCLE_NODE(MINIMUM, luci::CircleMinimum)
CIRCLE_NODE(MIRROR_PAD, luci::CircleMirrorPad)
CIRCLE_NODE(MUL, luci::CircleMul)
CIRCLE_NODE(NEG, luci::CircleNeg)
+CIRCLE_NODE(NON_MAX_SUPPRESSION_V4, luci::CircleNonMaxSuppressionV4)
CIRCLE_NODE(NOT_EQUAL, luci::CircleNotEqual)
CIRCLE_NODE(ONE_HOT, luci::CircleOneHot)
CIRCLE_NODE(PACK, luci::CirclePack)
CIRCLE_NODE(PAD, luci::CirclePad)
+CIRCLE_NODE(PADV2, luci::CirclePadV2)
CIRCLE_NODE(POW, luci::CirclePow)
CIRCLE_NODE(PRELU, luci::CirclePRelu)
CIRCLE_NODE(RANGE, luci::CircleRange)
@@ -111,6 +112,7 @@ CIRCLE_NODE(TILE, luci::CircleTile)
CIRCLE_NODE(TOPK_V2, luci::CircleTopKV2)
CIRCLE_NODE(TRANSPOSE, luci::CircleTranspose)
CIRCLE_NODE(TRANSPOSE_CONV, luci::CircleTransposeConv)
+CIRCLE_NODE(UNIQUE, luci::CircleUnique)
CIRCLE_NODE(UNPACK, luci::CircleUnpack)
CIRCLE_NODE(WHERE, luci::CircleWhere)
CIRCLE_NODE(WHILE, luci::CircleWhile)
@@ -120,14 +122,17 @@ CIRCLE_NODE(BCQ_FULLY_CONNECTED, luci::CircleBCQFullyConnected)
CIRCLE_NODE(BCQ_GATHER, luci::CircleBCQGather)
CIRCLE_NODE(INSTANCE_NORM, luci::CircleInstanceNorm)
// Virtual node(s)
+CIRCLE_NODE(CIRCLECONST, luci::CircleConst)
CIRCLE_NODE(CIRCLEINPUT, luci::CircleInput)
CIRCLE_NODE(CIRCLEOUTPUT, luci::CircleOutput)
CIRCLE_NODE(CIRCLEOUTPUTDUMMY, luci::CircleOutputDummy)
CIRCLE_NODE(CIRCLEOUTPUTEXCLUDE, luci::CircleOutputExclude)
CIRCLE_NODE(CIRCLECUSTOMOUT, luci::CircleCustomOut)
CIRCLE_NODE(CIRCLEIFOUT, luci::CircleIfOut)
+CIRCLE_NODE(CIRCLENONMAXSUPPRESSIONV4OUT, luci::CircleNonMaxSuppressionV4Out)
CIRCLE_NODE(CIRCLESPLITOUT, luci::CircleSplitOut)
CIRCLE_NODE(CIRCLESPLITVOUT, luci::CircleSplitVOut)
CIRCLE_NODE(CIRCLETOPKV2OUT, luci::CircleTopKV2Out)
+CIRCLE_NODE(CIRCLEUNIQUEOUT, luci::CircleUniqueOut)
CIRCLE_NODE(CIRCLEUNPACKOUT, luci::CircleUnpackOut)
CIRCLE_NODE(CIRCLEWHILEOUT, luci::CircleWhileOut)
diff --git a/compiler/luci/lang/include/luci/IR/CircleQuantParam.h b/compiler/luci/lang/include/luci/IR/CircleQuantParam.h
index 7253e657b..694437303 100644
--- a/compiler/luci/lang/include/luci/IR/CircleQuantParam.h
+++ b/compiler/luci/lang/include/luci/IR/CircleQuantParam.h
@@ -29,6 +29,7 @@ struct CircleQuantParam
std::vector<float> max;
std::vector<float> scale;
std::vector<int64_t> zerop;
+ int32_t quantized_dimension{0};
};
} // namespace luci
diff --git a/compiler/luci/lang/include/luci/IR/Nodes/CircleConst.h b/compiler/luci/lang/include/luci/IR/Nodes/CircleConst.h
index fc671746f..250282049 100644
--- a/compiler/luci/lang/include/luci/IR/Nodes/CircleConst.h
+++ b/compiler/luci/lang/include/luci/IR/Nodes/CircleConst.h
@@ -31,7 +31,7 @@ namespace luci
* @brief Class to build tensor data
* @note This will not be exported as a specific op
*/
-class CircleConst final : public FixedArityNode<0, CircleNodeImpl<CircleOpcode::CONST>>
+class CircleConst final : public FixedArityNode<0, CircleNodeImpl<CircleOpcode::CIRCLECONST>>
{
public:
CircleConst() = default;
diff --git a/compiler/luci/lang/include/luci/IR/Nodes/CircleNonMaxSuppressionV4.h b/compiler/luci/lang/include/luci/IR/Nodes/CircleNonMaxSuppressionV4.h
new file mode 100644
index 000000000..69f3368c0
--- /dev/null
+++ b/compiler/luci/lang/include/luci/IR/Nodes/CircleNonMaxSuppressionV4.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LUCI_IR_CIRCLE_NON_MAX_SUPPRESSION_V4_H__
+#define __LUCI_IR_CIRCLE_NON_MAX_SUPPRESSION_V4_H__
+
+#include "luci/IR/CircleNodeDecl.h"
+#include "luci/IR/CircleOpcode.h"
+
+#include "luci/IR/LuciNodeMixins.h"
+
+namespace luci
+{
+
+/**
+ * @brief NON_MAX_SUPPRESSION_V4 in Circle
+ */
+class CircleNonMaxSuppressionV4 final
+ : public FixedArityNode<5, CircleNodeImpl<CircleOpcode::NON_MAX_SUPPRESSION_V4>>
+{
+public:
+ loco::Node *boxes(void) const { return at(0)->node(); }
+ void boxes(loco::Node *node) { at(0)->node(node); }
+
+ loco::Node *scores(void) const { return at(1)->node(); }
+ void scores(loco::Node *node) { at(1)->node(node); }
+
+ loco::Node *max_output_size(void) const { return at(2)->node(); }
+ void max_output_size(loco::Node *node) { at(2)->node(node); }
+
+ loco::Node *iou_threshold(void) const { return at(3)->node(); }
+ void iou_threshold(loco::Node *node) { at(3)->node(node); }
+
+ loco::Node *score_threshold(void) const { return at(4)->node(); }
+ void score_threshold(loco::Node *node) { at(4)->node(node); }
+};
+
+} // namespace luci
+
+#endif // __LUCI_IR_CIRCLE_NON_MAX_SUPPRESSION_V4_H__
diff --git a/compiler/luci/lang/include/luci/IR/Nodes/CircleNonMaxSuppressionV4Out.h b/compiler/luci/lang/include/luci/IR/Nodes/CircleNonMaxSuppressionV4Out.h
new file mode 100644
index 000000000..a24dc3e9c
--- /dev/null
+++ b/compiler/luci/lang/include/luci/IR/Nodes/CircleNonMaxSuppressionV4Out.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LUCI_IR_CIRCLE_NONMAXSUPPRESSIONV4OUT_H__
+#define __LUCI_IR_CIRCLE_NONMAXSUPPRESSIONV4OUT_H__
+
+#include "luci/IR/CircleNodeDecl.h"
+#include "luci/IR/CircleOpcode.h"
+
+#include "luci/IR/LuciNodeMixins.h"
+
+namespace luci
+{
+
+/**
+ * @brief Virtual NONMAXSUPPRESSIONV4OUT in Circle
+ */
+class CircleNonMaxSuppressionV4Out final
+ : public FixedArityNode<1, CircleNodeImpl<CircleOpcode::CIRCLENONMAXSUPPRESSIONV4OUT>>
+{
+public:
+ CircleNonMaxSuppressionV4Out() = default;
+
+public:
+ loco::Node *input(void) const { return at(0)->node(); }
+ void input(loco::Node *node) { at(0)->node(node); }
+
+public:
+ int32_t index(void) const { return _index; }
+ void index(int32_t index) { _index = index; }
+
+private:
+ int32_t _index{-1};
+};
+
+} // namespace luci
+
+#endif // __LUCI_IR_CIRCLE_NONMAXSUPPRESSIONV4OUT_H__
diff --git a/compiler/luci/lang/include/luci/IR/Nodes/CirclePadV2.h b/compiler/luci/lang/include/luci/IR/Nodes/CirclePadV2.h
new file mode 100644
index 000000000..563cfd9a4
--- /dev/null
+++ b/compiler/luci/lang/include/luci/IR/Nodes/CirclePadV2.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LUCI_IR_CIRCLEPADV2_H__
+#define __LUCI_IR_CIRCLEPADV2_H__
+
+#include "luci/IR/CircleNodeDecl.h"
+#include "luci/IR/CircleOpcode.h"
+
+#include "luci/IR/LuciNodeMixins.h"
+
+namespace luci
+{
+
+/**
+ * @brief PADV2 in Circle
+ */
+class CirclePadV2 final : public FixedArityNode<3, CircleNodeImpl<CircleOpcode::PADV2>>
+{
+public:
+ CirclePadV2() = default;
+
+public:
+ loco::Node *input(void) const { return at(0)->node(); }
+ void input(loco::Node *node) { at(0)->node(node); }
+
+ loco::Node *paddings(void) const { return at(1)->node(); }
+ void paddings(loco::Node *node) { at(1)->node(node); }
+
+ loco::Node *constant_values(void) const { return at(2)->node(); }
+ void constant_values(loco::Node *node) { at(2)->node(node); }
+};
+
+} // namespace luci
+
+#endif // __LUCI_IR_CIRCLEPADV2_H__
diff --git a/compiler/luci/lang/include/luci/IR/Nodes/CircleUnique.h b/compiler/luci/lang/include/luci/IR/Nodes/CircleUnique.h
new file mode 100644
index 000000000..719a72362
--- /dev/null
+++ b/compiler/luci/lang/include/luci/IR/Nodes/CircleUnique.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LUCI_IR_CIRCELUNIQUE_H__
+#define __LUCI_IR_CIRCELUNIQUE_H__
+
+#include "luci/IR/CircleNodeDecl.h"
+#include "luci/IR/CircleOpcode.h"
+
+#include "luci/IR/LuciNodeMixins.h"
+
+namespace luci
+{
+
+/**
+ * @brief Unique in Circle
+ */
+class CircleUnique final : public FixedArityNode<1, CircleNodeImpl<CircleOpcode::UNIQUE>>
+{
+public:
+ loco::Node *input(void) const { return at(0)->node(); }
+ void input(loco::Node *node) { at(0)->node(node); }
+
+public:
+ loco::DataType idx_out_type(void) const { return _idx_out_type; }
+ void output_type(loco::DataType ot) { _idx_out_type = ot; }
+
+private:
+ loco::DataType _idx_out_type{loco::DataType::S32};
+};
+
+} // namespace luci
+
+#endif // __LUCI_IR_CIRCELUNIQUE_H__
diff --git a/compiler/luci/lang/include/luci/IR/Nodes/CircleUniqueOut.h b/compiler/luci/lang/include/luci/IR/Nodes/CircleUniqueOut.h
new file mode 100644
index 000000000..f846403e0
--- /dev/null
+++ b/compiler/luci/lang/include/luci/IR/Nodes/CircleUniqueOut.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LUCI_IR_CIRCLE_UNIQUEOUT_H__
+#define __LUCI_IR_CIRCLE_UNIQUEOUT_H__
+
+#include "luci/IR/CircleNodeDecl.h"
+#include "luci/IR/CircleOpcode.h"
+
+#include "luci/IR/LuciNodeMixins.h"
+
+namespace luci
+{
+
+/**
+ * @brief Virtual CIRCLEUNIQUEOUT in Circle
+ */
+class CircleUniqueOut final
+ : public FixedArityNode<1, CircleNodeImpl<CircleOpcode::CIRCLEUNIQUEOUT>>
+{
+public:
+ CircleUniqueOut() = default;
+
+public:
+ loco::Node *input(void) const { return at(0)->node(); }
+ void input(loco::Node *node) { at(0)->node(node); }
+
+public:
+ int32_t index(void) const { return _index; }
+ void index(int32_t index) { _index = index; }
+
+private:
+ int32_t _index{-1};
+};
+
+} // namespace luci
+
+#endif // __LUCI_IR_CIRCLE_UNIQUEOUT_H__
diff --git a/compiler/luci/lang/src/Module.test.cpp b/compiler/luci/lang/src/Module.test.cpp
index 26bf073be..a5973e52d 100644
--- a/compiler/luci/lang/src/Module.test.cpp
+++ b/compiler/luci/lang/src/Module.test.cpp
@@ -22,7 +22,7 @@ TEST(ModuleTest, consturctor)
{
auto gs = luci::make_module();
- GTEST_SUCCEED();
+ SUCCEED();
}
TEST(ModuleTest, add)
diff --git a/compiler/luci/lang/src/Nodes/CircleCustom.test.cpp b/compiler/luci/lang/src/Nodes/CircleCustom.test.cpp
index 74ea82c6c..c07268cbf 100644
--- a/compiler/luci/lang/src/Nodes/CircleCustom.test.cpp
+++ b/compiler/luci/lang/src/Nodes/CircleCustom.test.cpp
@@ -35,7 +35,12 @@ TEST(CircleCustomTest, constructor)
ASSERT_EQ(0, custom_node.custom_code().size());
}
-TEST(CircleCustomTest, constructor_NEG) { ASSERT_DEBUG_DEATH(luci::CircleCustom{0}, ""); }
+TEST(CircleCustomTest, constructor_NEG)
+{
+ ASSERT_DEBUG_DEATH(luci::CircleCustom{0}, "");
+
+ SUCCEED();
+}
TEST(CircleCustomTest, invalidIndex_NEG)
{
diff --git a/compiler/luci/lang/src/Nodes/CircleIf.test.cpp b/compiler/luci/lang/src/Nodes/CircleIf.test.cpp
index e3c8c9f60..35f28e9ac 100644
--- a/compiler/luci/lang/src/Nodes/CircleIf.test.cpp
+++ b/compiler/luci/lang/src/Nodes/CircleIf.test.cpp
@@ -41,11 +41,15 @@ TEST(CircleIfTest, constructor)
TEST(CircleIfTestDeath, invalid_arity_NEG)
{
ASSERT_DEBUG_DEATH(luci::CircleIf very_long_name_if_node(0, 1), "");
+
+ SUCCEED();
}
TEST(CircleIfTestDeath, invalid_output_count_NEG)
{
ASSERT_DEBUG_DEATH(luci::CircleIf if_node(2, 0), "");
+
+ SUCCEED();
}
TEST(CircleIfTestDeath, invalid_input_get_index_NEG)
diff --git a/compiler/luci/lang/src/Nodes/CircleNonMaxSuppressionV4.test.cpp b/compiler/luci/lang/src/Nodes/CircleNonMaxSuppressionV4.test.cpp
new file mode 100644
index 000000000..b25ce4d6d
--- /dev/null
+++ b/compiler/luci/lang/src/Nodes/CircleNonMaxSuppressionV4.test.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "luci/IR/Nodes/CircleNonMaxSuppressionV4.h"
+
+#include "luci/IR/CircleDialect.h"
+#include "luci/IR/CircleNodeVisitor.h"
+
+#include <gtest/gtest.h>
+
+TEST(CircleNonMaxSuppressionV4Test, constructor)
+{
+ luci::CircleNonMaxSuppressionV4 nmsv4_node;
+
+ ASSERT_EQ(luci::CircleDialect::get(), nmsv4_node.dialect());
+ ASSERT_EQ(luci::CircleOpcode::NON_MAX_SUPPRESSION_V4, nmsv4_node.opcode());
+
+ ASSERT_EQ(nullptr, nmsv4_node.boxes());
+ ASSERT_EQ(nullptr, nmsv4_node.scores());
+ ASSERT_EQ(nullptr, nmsv4_node.max_output_size());
+ ASSERT_EQ(nullptr, nmsv4_node.iou_threshold());
+ ASSERT_EQ(nullptr, nmsv4_node.score_threshold());
+}
+
+TEST(CircleNonMaxSuppressionV4Test, input_NEG)
+{
+ luci::CircleNonMaxSuppressionV4 nmsv4_node;
+ luci::CircleNonMaxSuppressionV4 node;
+
+ nmsv4_node.boxes(&node);
+ nmsv4_node.scores(&node);
+ nmsv4_node.max_output_size(&node);
+ nmsv4_node.iou_threshold(&node);
+ nmsv4_node.score_threshold(&node);
+ ASSERT_NE(nullptr, nmsv4_node.boxes());
+ ASSERT_NE(nullptr, nmsv4_node.scores());
+ ASSERT_NE(nullptr, nmsv4_node.max_output_size());
+ ASSERT_NE(nullptr, nmsv4_node.iou_threshold());
+ ASSERT_NE(nullptr, nmsv4_node.score_threshold());
+
+ nmsv4_node.boxes(nullptr);
+ nmsv4_node.scores(nullptr);
+ nmsv4_node.max_output_size(nullptr);
+ nmsv4_node.iou_threshold(nullptr);
+ nmsv4_node.score_threshold(nullptr);
+ ASSERT_EQ(nullptr, nmsv4_node.boxes());
+ ASSERT_EQ(nullptr, nmsv4_node.scores());
+ ASSERT_EQ(nullptr, nmsv4_node.max_output_size());
+ ASSERT_EQ(nullptr, nmsv4_node.iou_threshold());
+ ASSERT_EQ(nullptr, nmsv4_node.score_threshold());
+}
+
+TEST(CircleNonMaxSuppressionV4Test, arity_NEG)
+{
+ luci::CircleNonMaxSuppressionV4 nmsv4_node;
+
+ ASSERT_NO_THROW(nmsv4_node.arg(4));
+ ASSERT_THROW(nmsv4_node.arg(5), std::out_of_range);
+}
+
+TEST(CircleNonMaxSuppressionV4Test, visit_mutable_NEG)
+{
+ struct TestVisitor final : public luci::CircleNodeMutableVisitor<void>
+ {
+ };
+
+ luci::CircleNonMaxSuppressionV4 nmsv4_node;
+
+ TestVisitor tv;
+ ASSERT_THROW(nmsv4_node.accept(&tv), std::exception);
+}
+
+TEST(CircleNonMaxSuppressionV4Test, visit_NEG)
+{
+ struct TestVisitor final : public luci::CircleNodeVisitor<void>
+ {
+ };
+
+ luci::CircleNonMaxSuppressionV4 nmsv4_node;
+
+ TestVisitor tv;
+ ASSERT_THROW(nmsv4_node.accept(&tv), std::exception);
+}
diff --git a/compiler/luci/lang/src/Nodes/CircleNonMaxSuppressionV4Out.test.cpp b/compiler/luci/lang/src/Nodes/CircleNonMaxSuppressionV4Out.test.cpp
new file mode 100644
index 000000000..c6cef4e91
--- /dev/null
+++ b/compiler/luci/lang/src/Nodes/CircleNonMaxSuppressionV4Out.test.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "luci/IR/Nodes/CircleNonMaxSuppressionV4Out.h"
+
+#include "luci/IR/CircleDialect.h"
+
+#include <gtest/gtest.h>
+
+TEST(CircleNonMaxSuppressionV4OutTest, constructor)
+{
+ luci::CircleNonMaxSuppressionV4Out vout_node;
+
+ ASSERT_EQ(luci::CircleDialect::get(), vout_node.dialect());
+ ASSERT_EQ(luci::CircleOpcode::CIRCLENONMAXSUPPRESSIONV4OUT, vout_node.opcode());
+
+ ASSERT_EQ(nullptr, vout_node.input());
+ ASSERT_EQ(-1, vout_node.index());
+}
diff --git a/compiler/luci/lang/src/Nodes/CirclePadV2.test.cpp b/compiler/luci/lang/src/Nodes/CirclePadV2.test.cpp
new file mode 100644
index 000000000..e09d517b2
--- /dev/null
+++ b/compiler/luci/lang/src/Nodes/CirclePadV2.test.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "luci/IR/Nodes/CirclePadV2.h"
+
+#include "luci/IR/CircleDialect.h"
+#include "luci/IR/CircleNodeVisitor.h"
+
+#include <gtest/gtest.h>
+
+TEST(CirclePadV2Test, constructor_P)
+{
+ luci::CirclePadV2 node;
+
+ ASSERT_EQ(luci::CircleDialect::get(), node.dialect());
+ ASSERT_EQ(luci::CircleOpcode::PADV2, node.opcode());
+
+ ASSERT_EQ(nullptr, node.input());
+ ASSERT_EQ(nullptr, node.paddings());
+ ASSERT_EQ(nullptr, node.constant_values());
+}
+
+TEST(CirclePadV2Test, input_NEG)
+{
+ luci::CirclePadV2 pad_node;
+ luci::CirclePadV2 node;
+
+ pad_node.input(&node);
+ pad_node.paddings(&node);
+ pad_node.constant_values(&node);
+ ASSERT_NE(nullptr, pad_node.input());
+ ASSERT_NE(nullptr, pad_node.paddings());
+ ASSERT_NE(nullptr, pad_node.constant_values());
+
+ pad_node.input(nullptr);
+ pad_node.paddings(nullptr);
+ pad_node.constant_values(nullptr);
+ ASSERT_EQ(nullptr, pad_node.input());
+ ASSERT_EQ(nullptr, pad_node.paddings());
+ ASSERT_EQ(nullptr, pad_node.constant_values());
+}
+
+TEST(CirclePadV2Test, arity_NEG)
+{
+ luci::CirclePadV2 pad_node;
+
+ ASSERT_NO_THROW(pad_node.arg(2));
+ ASSERT_THROW(pad_node.arg(3), std::out_of_range);
+}
+
+TEST(CirclePadV2Test, visit_mutable_NEG)
+{
+ struct TestVisitor final : public luci::CircleNodeMutableVisitor<void>
+ {
+ };
+
+ luci::CirclePadV2 pad_node;
+
+ TestVisitor tv;
+ ASSERT_THROW(pad_node.accept(&tv), std::exception);
+}
+
+TEST(CirclePadV2Test, visit_NEG)
+{
+ struct TestVisitor final : public luci::CircleNodeVisitor<void>
+ {
+ };
+
+ luci::CirclePadV2 pad_node;
+
+ TestVisitor tv;
+ ASSERT_THROW(pad_node.accept(&tv), std::exception);
+}
diff --git a/compiler/luci/lang/src/Nodes/CircleUnique.test.cpp b/compiler/luci/lang/src/Nodes/CircleUnique.test.cpp
new file mode 100644
index 000000000..517ee97d5
--- /dev/null
+++ b/compiler/luci/lang/src/Nodes/CircleUnique.test.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "luci/IR/Nodes/CircleUnique.h"
+
+#include "luci/IR/CircleDialect.h"
+#include "luci/IR/CircleNodeVisitor.h"
+
+#include <gtest/gtest.h>
+
+TEST(CircleUniqueTest, constructor)
+{
+ luci::CircleUnique unique_node;
+
+ ASSERT_EQ(luci::CircleDialect::get(), unique_node.dialect());
+ ASSERT_EQ(luci::CircleOpcode::UNIQUE, unique_node.opcode());
+
+ ASSERT_EQ(nullptr, unique_node.input());
+}
+
+TEST(CircleUniqueTest, input_NEG)
+{
+ luci::CircleUnique unique_node;
+ luci::CircleUnique node;
+
+ unique_node.input(&node);
+ ASSERT_NE(nullptr, unique_node.input());
+
+ unique_node.input(nullptr);
+ ASSERT_EQ(nullptr, unique_node.input());
+}
+
+TEST(CircleUniqueTest, arity_NEG)
+{
+ luci::CircleUnique unique_node;
+
+ ASSERT_NO_THROW(unique_node.arg(0));
+ ASSERT_THROW(unique_node.arg(1), std::out_of_range);
+}
+
+TEST(CircleUniqueTest, visit_mutable_NEG)
+{
+ struct TestVisitor final : public luci::CircleNodeMutableVisitor<void>
+ {
+ };
+
+ luci::CircleUnique unique_node;
+
+ TestVisitor tv;
+ ASSERT_THROW(unique_node.accept(&tv), std::exception);
+}
+
+TEST(CircleUniqueTest, visit_NEG)
+{
+ struct TestVisitor final : public luci::CircleNodeVisitor<void>
+ {
+ };
+
+ luci::CircleUnique unique_node;
+
+ TestVisitor tv;
+ ASSERT_THROW(unique_node.accept(&tv), std::exception);
+}
diff --git a/compiler/luci/lang/src/Nodes/CircleWhile.test.cpp b/compiler/luci/lang/src/Nodes/CircleWhile.test.cpp
index 19290c0a2..913686fbd 100644
--- a/compiler/luci/lang/src/Nodes/CircleWhile.test.cpp
+++ b/compiler/luci/lang/src/Nodes/CircleWhile.test.cpp
@@ -41,11 +41,15 @@ TEST(CircleWhileTest, constructor)
TEST(CircleWhileTestDeath, invalid_arity_NEG)
{
ASSERT_DEBUG_DEATH(luci::CircleWhile very_long_name_while_node(0, 1), "");
+
+ SUCCEED();
}
TEST(CircleWhileTestDeath, invalid_output_count_NEG)
{
ASSERT_DEBUG_DEATH(luci::CircleWhile while_node(2, 0), "");
+
+ SUCCEED();
}
TEST(CircleWhileTestDeath, invalid_input_get_index_NEG)
diff --git a/compiler/luci/logex/src/FormattedGraph.cpp b/compiler/luci/logex/src/FormattedGraph.cpp
index 4725ee3df..f04a418ef 100644
--- a/compiler/luci/logex/src/FormattedGraph.cpp
+++ b/compiler/luci/logex/src/FormattedGraph.cpp
@@ -244,6 +244,7 @@ private:
IMPLEMENT(luci::CircleMirrorPad)
IMPLEMENT(luci::CircleMul)
IMPLEMENT(luci::CircleNeg)
+ IMPLEMENT(luci::CircleNonMaxSuppressionV4)
IMPLEMENT(luci::CircleNotEqual)
IMPLEMENT(luci::CircleOneHot)
IMPLEMENT(luci::CirclePack)
@@ -291,6 +292,7 @@ private:
IMPLEMENT(luci::CircleTopKV2)
IMPLEMENT(luci::CircleTranspose)
IMPLEMENT(luci::CircleTransposeConv)
+ IMPLEMENT(luci::CircleUnique)
IMPLEMENT(luci::CircleUnpack)
IMPLEMENT(luci::CircleWhere)
IMPLEMENT(luci::CircleWhile)
@@ -303,9 +305,11 @@ private:
IMPLEMENT(luci::CircleInput)
IMPLEMENT(luci::CircleOutput)
IMPLEMENT(luci::CircleIfOut)
+ IMPLEMENT(luci::CircleNonMaxSuppressionV4Out)
IMPLEMENT(luci::CircleSplitOut)
IMPLEMENT(luci::CircleSplitVOut)
IMPLEMENT(luci::CircleTopKV2Out)
+ IMPLEMENT(luci::CircleUniqueOut)
IMPLEMENT(luci::CircleUnpackOut)
IMPLEMENT(luci::CircleWhileOut)
#undef IMPLEMENT
@@ -823,6 +827,19 @@ bool CircleNodeSummaryBuilder::summary(const luci::CircleNeg *node, locop::NodeS
return use_x(tbl(), node, s);
}
+bool CircleNodeSummaryBuilder::summary(const luci::CircleNonMaxSuppressionV4 *node,
+ locop::NodeSummary &s) const
+{
+ s.args().append("boxes", pepper::str(node->boxes()));
+ s.args().append("scores", pepper::str(node->scores()));
+ s.args().append("max_output_size", pepper::str(node->max_output_size()));
+ s.args().append("iou_threshold", pepper::str(node->iou_threshold()));
+ s.args().append("score_threshold", pepper::str(node->score_threshold()));
+
+ s.state(locop::NodeSummary::State::Complete);
+ return true;
+}
+
bool CircleNodeSummaryBuilder::summary(const luci::CircleNotEqual *node,
locop::NodeSummary &s) const
{
@@ -1227,6 +1244,14 @@ bool CircleNodeSummaryBuilder::summary(const luci::CircleTransposeConv *node,
return true;
}
+bool CircleNodeSummaryBuilder::summary(const luci::CircleUnique *node, locop::NodeSummary &s) const
+{
+ s.args().append("input", tbl()->lookup(node->input()));
+ s.args().append("idx_out_type", to_str(node->idx_out_type()));
+ s.state(locop::NodeSummary::State::Complete);
+ return true;
+}
+
bool CircleNodeSummaryBuilder::summary(const luci::CircleUnpack *node, locop::NodeSummary &s) const
{
s.args().append("value", tbl()->lookup(node->value()));
@@ -1293,6 +1318,16 @@ bool CircleNodeSummaryBuilder::summary(const luci::CircleTopKV2Out *node,
return true;
}
+bool CircleNodeSummaryBuilder::summary(const luci::CircleUniqueOut *node,
+ locop::NodeSummary &s) const
+{
+ s.args().append("unique", tbl()->lookup(node->input()));
+
+ s.state(locop::NodeSummary::State::Complete);
+
+ return true;
+}
+
bool CircleNodeSummaryBuilder::summary(const luci::CircleUnpackOut *node,
locop::NodeSummary &s) const
{
@@ -1308,6 +1343,12 @@ bool CircleNodeSummaryBuilder::summary(const luci::CircleIfOut *node, locop::Nod
return use_input(tbl(), node, s);
}
+bool CircleNodeSummaryBuilder::summary(const luci::CircleNonMaxSuppressionV4Out *node,
+ locop::NodeSummary &s) const
+{
+ return use_input(tbl(), node, s);
+}
+
bool CircleNodeSummaryBuilder::summary(const luci::CircleWhileOut *node,
locop::NodeSummary &s) const
{
diff --git a/compiler/luci/pass/src/CircleOptimizer.cpp b/compiler/luci/pass/src/CircleOptimizer.cpp
index 90fbe9009..2edf7a9c6 100644
--- a/compiler/luci/pass/src/CircleOptimizer.cpp
+++ b/compiler/luci/pass/src/CircleOptimizer.cpp
@@ -145,7 +145,7 @@ void CircleOptimizer::quantize(loco::Graph *g) const
{
static const std::vector<std::string> fakeq_supported_input_dtype{"float32"};
static const std::vector<std::string> fakeq_supported_output_dtype{"uint8"};
- static const std::vector<std::string> fakeq_supported_granularity{"layer"};
+ static const std::vector<std::string> fakeq_supported_granularity{"layer", "channel"};
auto input_dtype = _options->param(Options::AlgorithmParameters::Quantize_input_dtype);
auto output_dtype = _options->param(Options::AlgorithmParameters::Quantize_output_dtype);
@@ -173,7 +173,7 @@ void CircleOptimizer::quantize(loco::Graph *g) const
{
static const std::vector<std::string> qwmm_supported_input_dtype{"float32"};
static const std::vector<std::string> qwmm_supported_output_dtype{"uint8"};
- static const std::vector<std::string> qwmm_supported_granularity{"layer"};
+ static const std::vector<std::string> qwmm_supported_granularity{"layer", "channel"};
auto input_dtype = _options->param(Options::AlgorithmParameters::Quantize_input_dtype);
auto output_dtype = _options->param(Options::AlgorithmParameters::Quantize_output_dtype);
diff --git a/compiler/luci/pass/src/FuseBCQPass.cpp b/compiler/luci/pass/src/FuseBCQPass.cpp
index b81db8827..260de5b30 100644
--- a/compiler/luci/pass/src/FuseBCQPass.cpp
+++ b/compiler/luci/pass/src/FuseBCQPass.cpp
@@ -53,6 +53,11 @@ const std::string node_name_prefix(luci::NodeName node_name)
const auto index = prefix.find("Tensordot/");
prefix = prefix.substr(0, index - 1);
}
+ else if (prefix.find("/MatMul") != std::string::npos)
+ {
+ const auto index = prefix.find("/MatMul");
+ prefix = prefix.substr(0, index);
+ }
else if (prefix.find("kernel/") != std::string::npos)
{
const auto index = prefix.find("kernel/");
@@ -67,14 +72,190 @@ const std::string node_name_prefix(luci::NodeName node_name)
return prefix;
}
+/**
+ * @brief Create CircleOutputExclude operation, which has same shape and dtype with
+ * original circle_node.
+ */
+luci::CircleOutputExclude *createNoOp(luci::CircleNode *circle_node)
+{
+ auto graph = circle_node->graph();
+ auto noOp = graph->nodes()->create<luci::CircleOutputExclude>();
+
+ if (circle_node->shape_status() == luci::ShapeStatus::VALID)
+ {
+ noOp->dtype(circle_node->dtype());
+ noOp->rank(circle_node->rank());
+ for (uint32_t i = 0; i < circle_node->rank(); ++i)
+ noOp->dim(i) = circle_node->dim(i);
+ }
+ else
+ {
+ // For type inference
+ noOp->dtype(loco::DataType::FLOAT32);
+ }
+
+ return noOp;
+};
+
} // namespace
namespace
{
-class BCQConverter final
+// V means the version of BCQ.
+template <int32_t V> class BCQFuser;
+
+template <> class BCQFuser<1>
{
public:
+ bool fuseBCQ(loco::Graph *g)
+ {
+ bool changed = false;
+
+ for (auto node : loco::all_nodes(g))
+ {
+ if (auto circle_const = dynamic_cast<luci::CircleConst *>(node))
+ {
+ add_BCQ_info_node(circle_const);
+ }
+ }
+
+ if (!is_bcqinfo_valid())
+ return false;
+
+ for (auto node : loco::active_nodes(loco::output_nodes(g)))
+ {
+ if (auto gather = dynamic_cast<luci::CircleGather *>(node))
+ {
+ auto params = dynamic_cast<luci::CircleConst *>(gather->params());
+ if (params != nullptr && has_BCQ_info(params))
+ {
+ auto bcq_gather = g->nodes()->create<luci::CircleBCQGather>();
+
+ bcq_gather->op_version(1);
+ bcq_gather->input_scales(get_alpha(params));
+ bcq_gather->input_binary(get_packed_binary_code(params));
+ bcq_gather->indices(gather->indices());
+ bcq_gather->input_clusters(packed_clusters(params));
+
+ // input_binary shape : [output_size, hidden_size]
+ const auto binary_hidden_size =
+ loco::must_cast<luci::CircleConst *>(bcq_gather->input_binary())->dim(1).value() * 32;
+ bcq_gather->input_hidden_size(binary_hidden_size);
+
+ if (do_w_x(params))
+ {
+ bcq_gather->axis(gather->axis());
+ }
+ else
+ {
+ const auto axis_transpose = (gather->axis() == 0) ? 1 : 0;
+ bcq_gather->axis(axis_transpose);
+ }
+
+ loco::replace(gather).with(bcq_gather);
+
+ changed = true;
+ }
+ }
+ else if (auto fully_connected = dynamic_cast<luci::CircleFullyConnected *>(node))
+ {
+ auto weights = dynamic_cast<luci::CircleConst *>(fully_connected->weights());
+ if (weights != nullptr && has_BCQ_info(weights))
+ {
+ auto bcq_fc = g->nodes()->create<luci::CircleBCQFullyConnected>();
+
+ bcq_fc->op_version(1);
+ bcq_fc->weights_scales(get_alpha(weights));
+ bcq_fc->weights_binary(get_packed_binary_code(weights));
+ bcq_fc->bias(fully_connected->bias());
+ bcq_fc->weights_clusters(packed_clusters(weights));
+ bcq_fc->fusedActivationFunction(fully_connected->fusedActivationFunction());
+
+ loco::Node *bcq_input = fully_connected->input();
+ int32_t batch_rank = 0;
+
+ // If input of BCQFullyConnected has more than rank 2, we should reshape it as rank 2
+ const auto original_input = loco::must_cast<luci::CircleNode *>(fully_connected->input());
+ if (original_input->shape_status() == luci::ShapeStatus::VALID &&
+ original_input->rank() > 2)
+ {
+ auto new_shape = g->nodes()->create<luci::CircleConst>();
+ new_shape->dtype(loco::DataType::S32);
+ new_shape->size<loco::DataType::S32>(2);
+ new_shape->rank(1);
+ new_shape->dim(0) = 2;
+
+ auto batch_size = 1;
+ for (uint32_t i = 0; i < original_input->rank() - 1; ++i)
+ batch_size *= original_input->dim(i).value();
+
+ new_shape->at<loco::DataType::S32>(0) = batch_size;
+ new_shape->at<loco::DataType::S32>(1) =
+ original_input->dim(original_input->rank() - 1).value();
+ new_shape->shape_status(luci::ShapeStatus::VALID);
+
+ auto reshape = g->nodes()->create<luci::CircleReshape>();
+ reshape->tensor(original_input);
+ reshape->shape(new_shape);
+
+ bcq_input = reshape;
+ batch_rank = original_input->rank() - 2;
+ }
+
+ // If x_w formation, we should insert Transpose in front and back of BCQFullyConnected
+ if (do_w_x(weights))
+ {
+ const auto binary_hidden_size =
+ loco::must_cast<luci::CircleNode *>(fully_connected->input())
+ ->dim(batch_rank)
+ .value();
+ bcq_fc->weights_hidden_size(binary_hidden_size);
+ bcq_fc->input(bcq_input);
+ loco::replace(fully_connected).with(bcq_fc);
+ }
+ else
+ {
+ const auto binary_hidden_size =
+ loco::must_cast<luci::CircleNode *>(fully_connected->input())
+ ->dim(1 + batch_rank)
+ .value();
+ bcq_fc->weights_hidden_size(binary_hidden_size);
+
+ auto perm = g->nodes()->create<luci::CircleConst>();
+ perm->dtype(loco::DataType::S32);
+ perm->size<loco::DataType::S32>(2);
+ perm->rank(1);
+ perm->dim(0) = 2;
+ perm->at<loco::DataType::S32>(0) = 1;
+ perm->at<loco::DataType::S32>(1) = 0;
+ perm->shape_status(luci::ShapeStatus::VALID);
+
+ auto input_transpose = g->nodes()->create<luci::CircleTranspose>();
+ input_transpose->a(bcq_input);
+ input_transpose->perm(perm);
+
+ bcq_fc->input(input_transpose);
+
+ auto output_transpose = g->nodes()->create<luci::CircleTranspose>();
+ output_transpose->a(bcq_fc);
+ output_transpose->perm(perm);
+
+ loco::replace(fully_connected).with(output_transpose);
+ }
+
+ changed = true;
+ }
+ }
+ }
+
+ if (changed)
+ clear_BCQ_nodes();
+
+ return changed;
+ }
+
+private:
void add_BCQ_info_node(luci::CircleConst *node)
{
const auto node_name = node->name();
@@ -119,16 +300,65 @@ public:
return has_info;
}
+ /**
+ * @brief Exclude BCQ information nodes which are used for fusing BCQ operations
+ * from graph output by using CircleOutputExclude
+ */
+ void clear_BCQ_nodes()
+ {
+ auto clear_nodes = [](std::map<std::string, luci::CircleConst *> &nodes) {
+ for (auto &n : nodes)
+ {
+ auto node = n.second;
+
+ for (auto s : loco::succs(node))
+ {
+ if (auto outnode = dynamic_cast<luci::CircleOutput *>(s))
+ {
+ outnode->from(createNoOp(node));
+ }
+ else if (auto reshape_node = dynamic_cast<luci::CircleReshape *>(s))
+ {
+ for (auto o : loco::succs(reshape_node))
+ {
+ auto circle_output = loco::must_cast<luci::CircleOutput *>(o);
+ circle_output->from(createNoOp(reshape_node));
+ }
+ }
+ }
+ }
+ };
+
+ clear_nodes(_do_w_x);
+ clear_nodes(_alpha);
+ clear_nodes(_packed_binary_code);
+ clear_nodes(_number_of_clusters);
+ clear_nodes(_size_of_clusters);
+ clear_nodes(_qbits_of_clusters);
+ clear_nodes(_dequant_weight);
+ }
+
+ bool is_bcqinfo_valid()
+ {
+ // do_w_x should be int32 or bool type
+ for (auto n : _do_w_x)
+ {
+ if (n.second->dtype() != loco::DataType::BOOL && n.second->dtype() != loco::DataType::S32)
+ return false;
+ }
+
+ return true;
+ }
+
+private:
bool do_w_x(luci::CircleConst *node)
{
const auto prefix = node_name_prefix(node->name());
if (_do_w_x[prefix]->dtype() == loco::DataType::S32)
return _do_w_x[prefix]->at<loco::DataType::S32>(0) == 1;
- else if (_do_w_x[prefix]->dtype() == loco::DataType::BOOL)
- return _do_w_x[prefix]->at<loco::DataType::BOOL>(0);
else
- throw std::runtime_error("do_w_x should be int or bool");
+ return _do_w_x[prefix]->at<loco::DataType::BOOL>(0);
}
luci::CircleConst *get_alpha(luci::CircleConst *node)
@@ -187,64 +417,6 @@ public:
return packed_clusters;
}
- /**
- * @brief Exclude BCQ information nodes which are used for fusing BCQ operations
- * from graph output by using CircleOutputExclude
- */
- void clear_BCQ_nodes()
- {
- auto createNoOp = [](luci::CircleNode *circle_node) {
- auto graph = circle_node->graph();
- auto noOp = graph->nodes()->create<luci::CircleOutputExclude>();
-
- if (circle_node->shape_status() == luci::ShapeStatus::VALID)
- {
- noOp->dtype(circle_node->dtype());
- noOp->rank(circle_node->rank());
- for (uint32_t i = 0; i < circle_node->rank(); ++i)
- noOp->dim(i) = circle_node->dim(i);
- }
- else
- {
- // For type inference
- noOp->dtype(loco::DataType::FLOAT32);
- }
-
- return noOp;
- };
-
- auto clear_nodes = [createNoOp](std::map<std::string, luci::CircleConst *> &nodes) {
- for (auto &n : nodes)
- {
- auto node = n.second;
-
- for (auto s : loco::succs(node))
- {
- if (auto outnode = dynamic_cast<luci::CircleOutput *>(s))
- {
- outnode->from(createNoOp(node));
- }
- else if (auto reshape_node = dynamic_cast<luci::CircleReshape *>(s))
- {
- for (auto o : loco::succs(reshape_node))
- {
- auto circle_output = loco::must_cast<luci::CircleOutput *>(o);
- circle_output->from(createNoOp(reshape_node));
- }
- }
- }
- }
- };
-
- clear_nodes(_do_w_x);
- clear_nodes(_alpha);
- clear_nodes(_packed_binary_code);
- clear_nodes(_number_of_clusters);
- clear_nodes(_size_of_clusters);
- clear_nodes(_qbits_of_clusters);
- clear_nodes(_dequant_weight);
- }
-
private:
std::map<std::string, luci::CircleConst *> _do_w_x;
std::map<std::string, luci::CircleConst *> _alpha;
@@ -262,143 +434,42 @@ namespace luci
bool FuseBCQPass::run(loco::Graph *g)
{
- BCQConverter converter;
-
bool changed = false;
+ // Find BCQ version information and check validity.
+ luci::CircleConst *version_node = nullptr;
for (auto node : loco::all_nodes(g))
{
if (auto circle_const = dynamic_cast<luci::CircleConst *>(node))
{
- converter.add_BCQ_info_node(circle_const);
- }
- }
-
- for (auto node : loco::active_nodes(loco::output_nodes(g)))
- {
- if (auto gather = dynamic_cast<luci::CircleGather *>(node))
- {
- auto params = dynamic_cast<luci::CircleConst *>(gather->params());
- if (params != nullptr && converter.has_BCQ_info(params))
+ if (circle_const->name().find("/bcqinfo_version") != std::string::npos)
{
- auto bcq_gather = g->nodes()->create<luci::CircleBCQGather>();
-
- bcq_gather->input_scales(converter.get_alpha(params));
- bcq_gather->input_binary(converter.get_packed_binary_code(params));
- bcq_gather->indices(gather->indices());
- bcq_gather->input_clusters(converter.packed_clusters(params));
-
- const auto binary_hidden_size =
- loco::must_cast<luci::CircleConst *>(bcq_gather->input_binary())->dim(1).value() * 32;
- bcq_gather->input_hidden_size(binary_hidden_size);
-
- if (converter.do_w_x(params))
- {
- bcq_gather->axis(gather->axis());
- }
- else
+ // There should be only one bcqinfo_version in the model
+ if (version_node != nullptr)
{
- const auto axis_transpose = (gather->axis() == 0) ? 1 : 0;
- bcq_gather->axis(axis_transpose);
+ assert(false && "Multiple version information found");
+ return false;
}
- loco::replace(gather).with(bcq_gather);
-
- changed = true;
+ version_node = circle_const;
}
}
- else if (auto fully_connected = dynamic_cast<luci::CircleFullyConnected *>(node))
- {
- auto weights = dynamic_cast<luci::CircleConst *>(fully_connected->weights());
- if (weights != nullptr && converter.has_BCQ_info(weights))
- {
- auto bcq_fc = g->nodes()->create<luci::CircleBCQFullyConnected>();
-
- bcq_fc->weights_scales(converter.get_alpha(weights));
- bcq_fc->weights_binary(converter.get_packed_binary_code(weights));
- bcq_fc->bias(fully_connected->bias());
- bcq_fc->weights_clusters(converter.packed_clusters(weights));
- bcq_fc->fusedActivationFunction(fully_connected->fusedActivationFunction());
-
- loco::Node *bcq_input = fully_connected->input();
- int32_t batch_rank = 0;
+ }
- // If input of BCQFullyConnected has more than rank 2, we should reshape it as rank 2
- const auto original_input = loco::must_cast<luci::CircleNode *>(fully_connected->input());
- if (original_input->shape_status() == ShapeStatus::VALID && original_input->rank() > 2)
- {
- auto new_shape = g->nodes()->create<luci::CircleConst>();
- new_shape->dtype(loco::DataType::S32);
- new_shape->size<loco::DataType::S32>(2);
- new_shape->rank(1);
- new_shape->dim(0) = 2;
-
- auto batch_size = 1;
- for (uint32_t i = 0; i < original_input->rank() - 1; ++i)
- batch_size *= original_input->dim(i).value();
-
- new_shape->at<loco::DataType::S32>(0) = batch_size;
- new_shape->at<loco::DataType::S32>(1) =
- original_input->dim(original_input->rank() - 1).value();
- new_shape->shape_status(ShapeStatus::VALID);
-
- auto reshape = g->nodes()->create<luci::CircleReshape>();
- reshape->tensor(original_input);
- reshape->shape(new_shape);
-
- bcq_input = reshape;
- batch_rank = original_input->rank() - 2;
- }
+ // If version node is not found, regard it as version 1.
+ int32_t bcq_version = (version_node != nullptr) ? version_node->at<loco::DataType::S32>(0) : 1;
- // If x_w formation, we should insert Transpose in front and back of BCQFullyConnected
- if (converter.do_w_x(weights))
- {
- const auto binary_hidden_size =
- loco::must_cast<luci::CircleNode *>(fully_connected->input())
- ->dim(batch_rank)
- .value();
- bcq_fc->weights_hidden_size(binary_hidden_size);
- bcq_fc->input(bcq_input);
- loco::replace(fully_connected).with(bcq_fc);
- }
- else
- {
- const auto binary_hidden_size =
- loco::must_cast<luci::CircleNode *>(fully_connected->input())
- ->dim(1 + batch_rank)
- .value();
- bcq_fc->weights_hidden_size(binary_hidden_size);
-
- auto perm = g->nodes()->create<luci::CircleConst>();
- perm->dtype(loco::DataType::S32);
- perm->size<loco::DataType::S32>(2);
- perm->rank(1);
- perm->dim(0) = 2;
- perm->at<loco::DataType::S32>(0) = 1;
- perm->at<loco::DataType::S32>(1) = 0;
- perm->shape_status(ShapeStatus::VALID);
-
- auto input_transpose = g->nodes()->create<luci::CircleTranspose>();
- input_transpose->a(bcq_input);
- input_transpose->perm(perm);
-
- bcq_fc->input(input_transpose);
-
- auto output_transpose = g->nodes()->create<luci::CircleTranspose>();
- output_transpose->a(bcq_fc);
- output_transpose->perm(perm);
-
- loco::replace(fully_connected).with(output_transpose);
- }
+ if (bcq_version == 1)
+ changed = BCQFuser<1>().fuseBCQ(g);
+ else
+ assert(false && "Not supported BCQ version");
- changed = true;
- }
- }
+ if (changed && version_node != nullptr)
+ {
+ // If BCQ is applied and version node was found, remove the node.
+ loco::replace(version_node).with(createNoOp(version_node));
}
- if (changed)
- converter.clear_BCQ_nodes();
-
return changed;
}
diff --git a/compiler/luci/pass/src/QuantizationUtils.cpp b/compiler/luci/pass/src/QuantizationUtils.cpp
index 6726ce746..e18690605 100644
--- a/compiler/luci/pass/src/QuantizationUtils.cpp
+++ b/compiler/luci/pass/src/QuantizationUtils.cpp
@@ -24,6 +24,13 @@
namespace luci
{
+uint8_t fp32_to_uint8_cast(float f)
+{
+ assert(std::numeric_limits<uint8_t>::min() <= f);
+ assert(f <= std::numeric_limits<uint8_t>::max());
+ return static_cast<uint8_t>(f);
+}
+
void compute_sym_scale_zp(float min, float max, float &scaling_factor, int64_t &zp,
float &nudged_min, float &nudged_max)
{
@@ -78,7 +85,7 @@ void compute_asym_scale_zp(float min, float max, float &scaling_factor, int64_t
}
else
zero_point_double = qmin_double - rmin / scale;
- if (zero_point_double <= qmin_double)
+ if (min >= 0)
{
assert(min >= 0 && max >= 0);
nudged_zero_point = kMinScale;
@@ -86,7 +93,7 @@ void compute_asym_scale_zp(float min, float max, float &scaling_factor, int64_t
if (min > 0 && max > 0)
WARN(l) << "The minimum and maximum values are all positive." << std::endl;
}
- else if (zero_point_double >= qmax_double)
+ else if (max < 0)
{
assert(min < 0 && max < 0);
nudged_zero_point = kMaxScale;
@@ -96,7 +103,14 @@ void compute_asym_scale_zp(float min, float max, float &scaling_factor, int64_t
else
{
assert(min < 0 && max >= 0);
- nudged_zero_point = static_cast<uint8_t>(std::round(zero_point_double));
+ nudged_zero_point = fp32_to_uint8_cast(std::round(zero_point_double));
+ }
+
+ // protect scale from being very low due to overflow
+ if (scale < 1e-5)
+ {
+ scale = 1e-5;
+ nudged_zero_point = fp32_to_uint8_cast(std::round(qmin_double - rmin / scale));
}
nudged_min = static_cast<float>((qmin_double - nudged_zero_point) * scale);
diff --git a/compiler/luci/pass/src/QuantizeWithMinMaxPass.cpp b/compiler/luci/pass/src/QuantizeWithMinMaxPass.cpp
index f8abee751..b335a53b4 100644
--- a/compiler/luci/pass/src/QuantizeWithMinMaxPass.cpp
+++ b/compiler/luci/pass/src/QuantizeWithMinMaxPass.cpp
@@ -138,7 +138,8 @@ bool is_quantized(const CircleNode *node)
node->dtype() == loco::DataType::S32; // bias
}
-void sym_wquant_per_channel(CircleConst *node, std::vector<float> &scaling_factor)
+void sym_wquant_per_channel(CircleConst *node, std::vector<float> &scaling_factor,
+ int32_t &channel_dim_index)
{
assert(node->dtype() == loco::DataType::FLOAT32);
@@ -153,7 +154,6 @@ void sym_wquant_per_channel(CircleConst *node, std::vector<float> &scaling_facto
uint32_t indices[4] = {
0,
};
- int channel_dim_index{0};
if (!get_channel_dim_index(node, dimension, channel_dim_index))
{
@@ -189,7 +189,7 @@ void sym_wquant_per_channel(CircleConst *node, std::vector<float> &scaling_facto
}
void asym_wquant_per_channel(CircleConst *node, std::vector<float> &min,
- std::vector<float> &scaling_factor)
+ std::vector<float> &scaling_factor, int32_t &channel_dim_index)
{
assert(node->dtype() == loco::DataType::FLOAT32);
@@ -204,7 +204,6 @@ void asym_wquant_per_channel(CircleConst *node, std::vector<float> &min,
uint32_t indices[4] = {
0,
};
- int channel_dim_index{0};
if (!get_channel_dim_index(node, dimension, channel_dim_index))
{
@@ -282,6 +281,10 @@ bool is_weights(CircleNode *node)
if (dw_conv != nullptr && dw_conv->filter() == circle_const)
return true;
+ auto t_conv = dynamic_cast<CircleTransposeConv *>(out);
+ if (t_conv != nullptr && t_conv->filter() == circle_const && circle_const->rank() == 4)
+ return true;
+
auto fc = dynamic_cast<CircleFullyConnected *>(out);
if (fc != nullptr && fc->weights() == circle_const)
return true;
@@ -350,8 +353,8 @@ struct QuantizeActivation final : public luci::CircleNodeMutableVisitor<bool>
circle_node->dtype(loco::DataType::S16);
}
- circle_node->quantparam()->max[0] = nudged_max;
- circle_node->quantparam()->min[0] = nudged_min;
+ circle_node->quantparam()->min.clear();
+ circle_node->quantparam()->max.clear();
circle_node->quantparam()->scale.push_back(scaling_factor);
circle_node->quantparam()->zerop.push_back(zp);
}
@@ -472,15 +475,19 @@ struct QuantizeWeights final : public luci::CircleNodeMutableVisitor<bool>
assert(quantparam != nullptr);
auto min = quantparam->min;
auto scaling_factor = quantparam->scale;
+ int32_t channel_dim_index = 0;
if (output_type == loco::DataType::U8)
{
- asym_wquant_per_channel(circle_const, min, scaling_factor);
+ asym_wquant_per_channel(circle_const, min, scaling_factor, channel_dim_index);
}
else
{
- sym_wquant_per_channel(circle_const, scaling_factor);
+ sym_wquant_per_channel(circle_const, scaling_factor, channel_dim_index);
}
+ quantparam->min.clear();
+ quantparam->max.clear();
+ quantparam->quantized_dimension = channel_dim_index;
}
// Find min/max per layer-wise
else
@@ -493,6 +500,8 @@ struct QuantizeWeights final : public luci::CircleNodeMutableVisitor<bool>
auto min = quantparam->min[0];
auto scaling_factor = quantparam->scale[0];
asym_wquant_per_layer(circle_const, min, scaling_factor);
+ quantparam->min.clear();
+ quantparam->max.clear();
}
}
}
diff --git a/compiler/luci/service/src/CircleShapeInferenceRule.cpp b/compiler/luci/service/src/CircleShapeInferenceRule.cpp
index a291cfe70..6355ec546 100644
--- a/compiler/luci/service/src/CircleShapeInferenceRule.cpp
+++ b/compiler/luci/service/src/CircleShapeInferenceRule.cpp
@@ -1010,6 +1010,12 @@ public:
loco::NodeShape visit(const luci::CircleNeg *node) final { return use_x(node); }
+ loco::NodeShape visit(const luci::CircleNonMaxSuppressionV4 *node) final
+ {
+ const auto boxes_shape = loco::shape_get(node->boxes()).as<loco::TensorShape>();
+ return loco::NodeShape{boxes_shape};
+ }
+
loco::NodeShape visit(const luci::CircleNotEqual *node) final { return broadcast_xy(node); }
loco::NodeShape visit(const luci::CircleOneHot *node) final
@@ -1818,6 +1824,18 @@ public:
return output_shape;
}
+ loco::NodeShape visit(const luci::CircleUnique *node) final
+ {
+ auto input_shape = loco::shape_get(node->input()).as<loco::TensorShape>();
+
+ assert(input_shape.rank() == 1);
+
+ loco::TensorShape shape_output;
+ shape_output = own_shape(node);
+
+ return loco::NodeShape{shape_output};
+ }
+
loco::NodeShape visit(const luci::CircleTransposeConv *node) final
{
// TransposeConv's output shape is written in its 'inputSizes' argument
@@ -2019,6 +2037,34 @@ public:
return loco::NodeShape{*then_graph_output->shape()};
}
+ loco::NodeShape visit(const luci::CircleNonMaxSuppressionV4Out *node) final
+ {
+ const loco::DataType S32 = loco::DataType::S32;
+
+ auto nmsv4 = dynamic_cast<const luci::CircleNonMaxSuppressionV4 *>(node->input());
+ if (nmsv4 == nullptr)
+ INTERNAL_EXN("CircleNonMaxSuppressionV4 IR is not configured correctly");
+
+ auto index = node->index();
+ if (index == 1)
+ return loco::TensorShape({0});
+
+ assert(index == 0);
+
+ auto unknown = loco::TensorShape{loco::Dimension()};
+ auto max_output_size = dynamic_cast<const luci::CircleConst *>(nmsv4->max_output_size());
+ if (max_output_size == nullptr)
+ return unknown; // we need CircleConst for max output size
+
+ LUCI_ASSERT(max_output_size->dtype() == S32, "Only support int32 for max_output_size");
+
+ if (max_output_size->size<S32>() < 1)
+ return unknown;
+
+ auto max_output_size_value = uint32_t(max_output_size->at<S32>(0));
+ return loco::TensorShape{max_output_size_value};
+ }
+
loco::NodeShape visit(const luci::CircleSplitOut *node) final
{
const loco::DataType S32 = loco::DataType::S32;
@@ -2142,6 +2188,19 @@ public:
return loco::NodeShape{output_shape};
}
+ loco::NodeShape visit(const luci::CircleUniqueOut *node) final
+ {
+ auto unique = dynamic_cast<const luci::CircleUnique *>(node->input());
+ if (unique == nullptr)
+ {
+ INTERNAL_EXN("CircleUnique IR is not configured correctly");
+ }
+
+ auto unique_shape = loco::shape_get(unique).as<loco::TensorShape>();
+
+ return loco::NodeShape{unique_shape};
+ }
+
loco::NodeShape visit(const luci::CircleUnpackOut *node) final
{
auto unpack = dynamic_cast<const luci::CircleUnpack *>(node->input());
diff --git a/compiler/luci/service/src/CircleTypeInferenceRule.cpp b/compiler/luci/service/src/CircleTypeInferenceRule.cpp
index de2ba3ea4..e7910bfc0 100644
--- a/compiler/luci/service/src/CircleTypeInferenceRule.cpp
+++ b/compiler/luci/service/src/CircleTypeInferenceRule.cpp
@@ -252,6 +252,11 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT
loco::DataType visit(const luci::CircleNeg *node) final { return loco::dtype_get(node->x()); }
+ loco::DataType visit(const luci::CircleNonMaxSuppressionV4 *node) final
+ {
+ return loco::dtype_get(node->boxes());
+ }
+
loco::DataType visit(const luci::CircleNotEqual *) final { return loco::DataType::BOOL; }
loco::DataType visit(const luci::CirclePack *node) final
@@ -345,7 +350,10 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT
return loco::dtype_get(node->tensor());
}
- loco::DataType visit(const luci::CircleResizeBilinear *) final { return loco::DataType::FLOAT32; }
+ loco::DataType visit(const luci::CircleResizeBilinear *node) final
+ {
+ return loco::dtype_get(node->input());
+ }
loco::DataType visit(const luci::CircleResizeNearestNeighbor *node) final
{
@@ -472,6 +480,11 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT
return loco::dtype_get(node->outBackprop());
}
+ loco::DataType visit(const luci::CircleUnique *node) final
+ {
+ return loco::dtype_get(node->input());
+ }
+
loco::DataType visit(const luci::CircleUnpack *node) final
{
return loco::dtype_get(node->value());
@@ -569,6 +582,13 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT
return then_graph_output->dtype();
}
+ loco::DataType visit(const luci::CircleNonMaxSuppressionV4Out *node) final
+ {
+ (void)node;
+ assert(node->index() == 0 || node->index() == 1);
+ return loco::DataType::S32;
+ }
+
loco::DataType visit(const luci::CircleSplitOut *node) final
{
return loco::dtype_get(node->input());
@@ -589,6 +609,17 @@ struct TypeInferenceAlgorithm final : public luci::CircleNodeVisitor<loco::DataT
return loco::DataType::S32;
}
+ loco::DataType visit(const luci::CircleUniqueOut *node) final
+ {
+ if (node->index() == 0)
+ {
+ return loco::dtype_get(node->input());
+ }
+ assert(node->index() == 1);
+ auto unique = loco::must_cast<luci::CircleUnique *>(node->input());
+ return unique->idx_out_type();
+ }
+
loco::DataType visit(const luci::CircleUnpackOut *node) final
{
return loco::dtype_get(node->input());
diff --git a/compiler/luci/tests/test.lst b/compiler/luci/tests/test.lst
index 188e29828..9fd42ed4e 100644
--- a/compiler/luci/tests/test.lst
+++ b/compiler/luci/tests/test.lst
@@ -20,6 +20,7 @@ addread(ArgMin_U8_001)
addread(ArgMin_U8_002)
addread(ArgMin_U8_003)
addread(AveragePool2D_000)
+addread(AveragePool2D_U8_000)
addread(BatchMatMul_000)
addread(BatchMatMulV2_000)
addread(BatchMatMulV2_001)
@@ -30,13 +31,16 @@ addread(Ceil_000)
addread(Concatenation_000)
addread(Concatenation_U8_000)
addread(Conv2D_000)
+addread(Conv2D_001)
addread(Conv2D_002)
addread(Conv2D_003)
addread(Conv2D_U8_000)
+addread(Conv2D_U8_001)
addread(Cos_000)
addread(DepthToSpace_000)
addread(DepthwiseConv2D_000)
addread(DepthwiseConv2D_U8_000)
+addread(DepthwiseConv2D_U8_001)
addread(DepthwiseConv2D_001)
addread(Div_000)
addread(ELU_000)
@@ -64,6 +68,7 @@ addread(GreaterEqual_000)
addread(If_000)
addread(If_001)
addread(L2Normalize_000)
+addread(L2Normalize_U8_000)
addread(L2Pool2D_000)
addread(L2Pool2D_U8_000)
addread(LeakyRelu_000)
@@ -75,6 +80,7 @@ addread(LogicalAnd_000)
addread(LogicalNot_000)
addread(LogicalOr_000)
addread(Logistic_000)
+addread(Logistic_U8_000)
addread(LogSoftmax_000)
addread(MatMul_000)
addread(MatrixDiag_000)
@@ -84,6 +90,7 @@ addread(MaxPool2D_000)
addread(MaxPool2D_U8_000)
addread(Mean_000)
addread(Mean_001)
+addread(Mean_U8_000)
addread(Minimum_000)
addread(MirrorPad_000)
addread(Mul_000)
@@ -97,6 +104,7 @@ addread(OneHot_003)
addread(Pack_000)
addread(Pack_U8_000)
addread(Pad_000)
+addread(Pad_U8_000)
addread(Pow_000)
addread(PRelu_000)
addread(Range_000)
@@ -212,6 +220,7 @@ addwrite(ArgMin_U8_001)
addwrite(ArgMin_U8_002)
addwrite(ArgMin_U8_003)
addwrite(AveragePool2D_000)
+addwrite(AveragePool2D_U8_000)
addwrite(BatchMatMul_000)
addwrite(BatchMatMulV2_000)
addwrite(BatchMatMulV2_001)
@@ -222,13 +231,16 @@ addwrite(Ceil_000)
addwrite(Concatenation_000)
addwrite(Concatenation_U8_000)
addwrite(Conv2D_000)
+addwrite(Conv2D_001)
addwrite(Conv2D_002)
addwrite(Conv2D_003)
addwrite(Conv2D_U8_000)
+addwrite(Conv2D_U8_001)
addwrite(Cos_000)
addwrite(DepthToSpace_000)
addwrite(DepthwiseConv2D_000)
addwrite(DepthwiseConv2D_U8_000)
+addwrite(DepthwiseConv2D_U8_001)
addwrite(DepthwiseConv2D_001)
addwrite(Div_000)
addwrite(ELU_000)
@@ -256,6 +268,7 @@ addwrite(GreaterEqual_000)
addwrite(If_000)
addwrite(If_001)
addwrite(L2Normalize_000)
+addwrite(L2Normalize_U8_000)
addwrite(L2Pool2D_000)
addwrite(L2Pool2D_U8_000)
addwrite(LeakyRelu_000)
@@ -267,6 +280,7 @@ addwrite(LogicalAnd_000)
addwrite(LogicalNot_000)
addwrite(LogicalOr_000)
addwrite(Logistic_000)
+addwrite(Logistic_U8_000)
addwrite(LogSoftmax_000)
addwrite(MatMul_000)
addwrite(MatrixDiag_000)
@@ -276,6 +290,7 @@ addwrite(MaxPool2D_000)
addwrite(MaxPool2D_U8_000)
addwrite(Mean_000)
addwrite(Mean_001)
+addwrite(Mean_U8_000)
addwrite(Minimum_000)
addwrite(MirrorPad_000)
addwrite(Mul_000)