diff options
author | Chunseok Lee <chunseok.lee@samsung.com> | 2020-08-14 15:19:19 +0900 |
---|---|---|
committer | Chunseok Lee <chunseok.lee@samsung.com> | 2020-08-14 15:19:19 +0900 |
commit | 042b262b3633b6c0f577aed6cb4b980ad0c1dcf3 (patch) | |
tree | e79fb9ffe65b21bdc5863306db2757ab187a3306 /compiler/luci | |
parent | 05e0ec30a632339a8533082476f27bda31ccde16 (diff) | |
download | nnfw-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')
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) |