diff --git a/compiler/luci/logex/CMakeLists.txt b/compiler/luci/logex/CMakeLists.txt index aed9fb79b32..7d45478d26d 100644 --- a/compiler/luci/logex/CMakeLists.txt +++ b/compiler/luci/logex/CMakeLists.txt @@ -1,5 +1,7 @@ # TODO Find how to test logging-ex utility file(GLOB_RECURSE SOURCES "src/*.cpp") +file(GLOB_RECURSE TESTS "src/*.test.cpp") +list(REMOVE_ITEM SOURCES ${TESTS}) if (NOT LUCI_LIBRARY_TYPE) set(LUCI_LIBRARY_TYPE "SHARED") @@ -13,7 +15,13 @@ target_link_libraries(luci_logex PRIVATE luci_log) target_link_libraries(luci_logex PRIVATE luci_lang) target_link_libraries(luci_logex PRIVATE hermes_std) target_link_libraries(luci_logex PRIVATE nncc_common) -target_link_libraries(luci_logex PRIVATE pepper_str) install(TARGETS luci_logex DESTINATION lib) install(DIRECTORY include/ DESTINATION include FILES_MATCHING PATTERN "*.h") + +nnas_find_package(GTest REQUIRED) + +GTest_AddTest(luci_logex_test ${TESTS}) +target_include_directories(luci_logex_test PRIVATE src) +target_link_libraries(luci_logex_test luci_logex) +target_link_libraries(luci_logex_test luci_lang) diff --git a/compiler/luci/logex/src/CircleNodeSummaryBuilder.cpp b/compiler/luci/logex/src/CircleNodeSummaryBuilder.cpp index 3239ee6a4df..34107952e52 100644 --- a/compiler/luci/logex/src/CircleNodeSummaryBuilder.cpp +++ b/compiler/luci/logex/src/CircleNodeSummaryBuilder.cpp @@ -15,6 +15,7 @@ */ #include "CircleNodeSummaryBuilder.h" +#include "CircleNodeSummaryBuilders.h" #include @@ -118,24 +119,28 @@ CircleNodeSummaryBuilder::create_builder(const luci::CircleNode *node) return std::make_unique(); \ } + CIRCLE_NODE(ABS, CircleAbsSummaryBuilder) + CIRCLE_NODE(ADD, CircleAddSummaryBuilder) + CIRCLE_NODE(ADD_N, CircleAddNSummaryBuilder) + CIRCLE_NODE(ARG_MAX, CircleArgMaxSummaryBuilder) + CIRCLE_NODE(ARG_MIN, CircleArgMinSummaryBuilder) + CIRCLE_NODE(AVERAGE_POOL_2D, CircleAveragePool2DSummaryBuilder) + CIRCLE_NODE(BATCH_MATMUL, CircleBatchMatMulSummaryBuilder) + CIRCLE_NODE(BATCH_TO_SPACE_ND, CircleBatchToSpaceNDSummaryBuilder) + CIRCLE_NODE(BCQ_FULLY_CONNECTED, CircleBCQFullyConnectedSummaryBuilder) + CIRCLE_NODE(BCQ_GATHER, CircleBCQGatherSummaryBuilder) + CIRCLE_NODE(BIDIRECTIONAL_SEQUENCE_LSTM, CircleBidirectionalSequenceLSTMSummaryBuilder) + CIRCLE_NODE(CAST, CircleCastSummaryBuilder) + CIRCLE_NODE(CEIL, CircleCeilSummaryBuilder) + CIRCLE_NODE(CONCATENATION, CircleConcatenationSummaryBuilder) + CIRCLE_NODE(CIRCLECONST, CircleConstSummaryBuilder) + CIRCLE_NODE(CONV_2D, CircleConv2DSummaryBuilder) + CIRCLE_NODE(COS, CircleCosSummaryBuilder) + CIRCLE_NODE(CUSTOM, CircleCustomSummaryBuilder) + // TODO Implement following builders - // CIRCLE_NODE(ABS, CircleAbsSummaryBuilder) - // CIRCLE_NODE(ADD, CircleAddSummaryBuilder) - // CIRCLE_NODE(ADD_N, CircleAddNSummaryBuilder) - // CIRCLE_NODE(ARG_MAX, CircleArgMaxSummaryBuilder) - // CIRCLE_NODE(ARG_MIN, CircleArgMinSummaryBuilder) - // CIRCLE_NODE(AVERAGE_POOL_2D, CircleAveragePool2DSummaryBuilder) - // CIRCLE_NODE(BATCH_MATMUL, CircleBatchMatMulSummaryBuilder) - // CIRCLE_NODE(BATCH_TO_SPACE_ND, CircleBatchToSpaceNDSummaryBuilder) - // CIRCLE_NODE(BCQ_FULLY_CONNECTED, CircleBCQFullyConnectedSummaryBuilder) - // CIRCLE_NODE(BCQ_GATHER, CircleBCQGatherSummaryBuilder) - // CIRCLE_NODE(BIDIRECTIONAL_SEQUENCE_LSTM, CircleBidirectionalSequenceLSTMSummaryBuilder) - // CIRCLE_NODE(CAST, CircleCastSummaryBuilder) - // CIRCLE_NODE(CEIL, CircleCeilSummaryBuilder) - // CIRCLE_NODE(CONCATENATION, CircleConcatenationSummaryBuilder) // CIRCLE_NODE(CIRCLEBIDIRECTIONAL_SEQUENCE_LSTM_OUT, // CircleBidirectionalSequenceLSTMOutSummaryBuilder) - // CIRCLE_NODE(CIRCLECONST, CircleConstSummaryBuilder) // CIRCLE_NODE(CIRCLECUSTOMOUT, CircleCustomOutSummaryBuilder) // CIRCLE_NODE(CIRCLEIFOUT, CircleIfOutSummaryBuilder) // CIRCLE_NODE(CIRCLENONMAXSUPPRESSIONV4OUT, CircleNonMaxSuppressionV4OutSummaryBuilder) @@ -147,9 +152,6 @@ CircleNodeSummaryBuilder::create_builder(const luci::CircleNode *node) // CIRCLE_NODE(CIRCLEUNPACKOUT, CircleUnpackOutSummaryBuilder) // CIRCLE_NODE(CIRCLEVARIABLE, CircleVariableSummaryBuilder) // CIRCLE_NODE(CIRCLEWHILEOUT, CircleWhileOutSummaryBuilder) - // CIRCLE_NODE(CONV_2D, CircleConv2DSummaryBuilder) - // CIRCLE_NODE(COS, CircleCosSummaryBuilder) - // CIRCLE_NODE(CUSTOM, CircleCustomSummaryBuilder) // CIRCLE_NODE(DEPTH_TO_SPACE, CircleDepthToSpaceSummaryBuilder) // CIRCLE_NODE(DEPTHWISE_CONV_2D, CircleDepthwiseConv2DSummaryBuilder) // CIRCLE_NODE(DEQUANTIZE, CircleDequantizeSummaryBuilder) diff --git a/compiler/luci/logex/src/CircleNodeSummaryBuilder.test.cpp b/compiler/luci/logex/src/CircleNodeSummaryBuilder.test.cpp new file mode 100644 index 00000000000..980622e7354 --- /dev/null +++ b/compiler/luci/logex/src/CircleNodeSummaryBuilder.test.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2022 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 "CircleNodeSummaryBuilder.h" + +#include +#include +#include + +#include + +namespace +{ + +class MockSymbolTable : public locop::SymbolTable +{ + std::string lookup(const loco::Node *) const override + { + return "Do nothing because it is mocking Symbol Table!"; + } +}; + +class CircleNodeSummaryBuilderTest : public ::testing::Test +{ +protected: + bool mock_build(const loco::Node *node) + { + return luci::CircleNodeSummaryBuilder().build(node, &_tbl, _s); + } + +protected: + MockSymbolTable _tbl; + locop::NodeSummary _s; +}; + +} // namespace + +TEST_F(CircleNodeSummaryBuilderTest, Add_validate) +{ + luci::CircleAdd node; + node.fusedActivationFunction(luci::FusedActFunc::RELU); + EXPECT_TRUE(mock_build(&node)); +} + +TEST_F(CircleNodeSummaryBuilderTest, Add_validate_fused_NEG) +{ + luci::CircleAdd node; + node.fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + EXPECT_FALSE(mock_build(&node)); +} + +TEST_F(CircleNodeSummaryBuilderTest, AveragePool2D_validate) +{ + luci::CircleAveragePool2D node; + node.fusedActivationFunction(luci::FusedActFunc::RELU); + node.padding(luci::Padding::SAME); + EXPECT_TRUE(mock_build(&node)); +} + +TEST_F(CircleNodeSummaryBuilderTest, AveragePool2D_validate_fused_NEG) +{ + luci::CircleAveragePool2D node; + node.fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + node.padding(luci::Padding::SAME); + EXPECT_FALSE(mock_build(&node)); +} + +TEST_F(CircleNodeSummaryBuilderTest, AveragePool2D_validate_padding_NEG) +{ + luci::CircleAveragePool2D node; + node.fusedActivationFunction(luci::FusedActFunc::RELU); + node.padding(luci::Padding::UNDEFINED); + EXPECT_FALSE(mock_build(&node)); +} + +TEST_F(CircleNodeSummaryBuilderTest, BCQFullyConnected_validate) +{ + luci::CircleBCQFullyConnected node; + node.fusedActivationFunction(luci::FusedActFunc::RELU); + EXPECT_TRUE(mock_build(&node)); +} + +TEST_F(CircleNodeSummaryBuilderTest, BCQFullyConnected_validate_fused_NEG) +{ + luci::CircleBCQFullyConnected node; + node.fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + EXPECT_FALSE(mock_build(&node)); +} + +TEST_F(CircleNodeSummaryBuilderTest, Concatenation_validate) +{ + luci::CircleConcatenation node(2); + node.fusedActivationFunction(luci::FusedActFunc::RELU); + EXPECT_TRUE(mock_build(&node)); +} + +TEST_F(CircleNodeSummaryBuilderTest, Concatenation_validate_fused_NEG) +{ + luci::CircleConcatenation node(2); + node.fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + EXPECT_FALSE(mock_build(&node)); +} + +TEST_F(CircleNodeSummaryBuilderTest, Conv2D_validate) +{ + luci::CircleConv2D node; + node.fusedActivationFunction(luci::FusedActFunc::RELU); + node.padding(luci::Padding::SAME); + EXPECT_TRUE(mock_build(&node)); +} + +TEST_F(CircleNodeSummaryBuilderTest, Conv2D_validate_fused_NEG) +{ + luci::CircleConv2D node; + node.fusedActivationFunction(luci::FusedActFunc::UNDEFINED); + node.padding(luci::Padding::SAME); + EXPECT_FALSE(mock_build(&node)); +} + +TEST_F(CircleNodeSummaryBuilderTest, Conv2D_validate_padding_NEG) +{ + luci::CircleConv2D node; + node.fusedActivationFunction(luci::FusedActFunc::RELU); + node.padding(luci::Padding::UNDEFINED); + EXPECT_FALSE(mock_build(&node)); +} diff --git a/compiler/luci/logex/src/CircleNodeSummaryBuilders.cpp b/compiler/luci/logex/src/CircleNodeSummaryBuilders.cpp new file mode 100644 index 00000000000..47f1b68d307 --- /dev/null +++ b/compiler/luci/logex/src/CircleNodeSummaryBuilders.cpp @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2022 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 "CircleNodeSummaryBuilders.h" + +#include +#include +#include + +#include +#include + +namespace +{ + +std::string to_str(loco::DataType type) +{ + switch (type) + { + case loco::DataType::U8: + return "UINT8"; + case loco::DataType::U16: + return "UINT16"; + case loco::DataType::U32: + return "UINT32"; + case loco::DataType::U64: + return "UINT64"; + + case loco::DataType::S8: + return "INT8"; + case loco::DataType::S16: + return "INT16"; + case loco::DataType::S32: + return "INT32"; + case loco::DataType::S64: + return "INT64"; + + case loco::DataType::FLOAT16: + return "FLOAT16"; + case loco::DataType::FLOAT32: + return "FLOAT32"; + case loco::DataType::FLOAT64: + return "FLOAT64"; + + case loco::DataType::BOOL: + return "BOOL"; + + default: + return "Error"; + } +} + +std::string to_str(bool value) { return value ? "true" : "false"; } + +std::string to_str(luci::FusedActFunc fused) +{ + switch (fused) + { + case luci::FusedActFunc::NONE: + return "NONE"; + case luci::FusedActFunc::RELU: + return "RELU"; + case luci::FusedActFunc::RELU_N1_TO_1: + return "RELU_N1_TO_1"; + case luci::FusedActFunc::RELU6: + return "RELU6"; + case luci::FusedActFunc::TANH: + return "TANH"; + case luci::FusedActFunc::SIGN_BIT: + return "SIGN_BIT"; + default: + return "Error"; + } +} + +std::string to_str(luci::Padding padding) +{ + switch (padding) + { + case luci::Padding::SAME: + return "SAME"; + case luci::Padding::VALID: + return "VALID"; + default: + return "Error"; + } +} + +std::string to_str(const luci::Stride *stride) +{ + return std::to_string(stride->h()) + "," + std::to_string(stride->w()); +} + +std::string to_str(const luci::Filter *filter) +{ + return std::to_string(filter->h()) + "," + std::to_string(filter->w()); +} + +} // namespace + +namespace luci +{ + +std::vector CircleNodeWithXSummaryBuilder::get_input_names(const luci::CircleNode *) +{ + return {"x"}; +} + +std::vector +CircleNodeWithINPUTSummaryBuilder::get_input_names(const luci::CircleNode *) +{ + return {"input"}; +} + +std::vector CircleNodeWithXYSummaryBuilder::get_input_names(const luci::CircleNode *) +{ + return {"x", "y"}; +} + +} // namespace luci + +namespace luci +{ + +bool CircleAddSummaryBuilder::validate(const luci::CircleNode *node) +{ + auto add = loco::must_cast(node); + if (add->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return false; + + return true; +} + +void CircleAddSummaryBuilder::build_attributes(const luci::CircleNode *node, locop::NodeSummary &s) +{ + auto add = loco::must_cast(node); + s.args().append("fused_activation_function", to_str(add->fusedActivationFunction())); +} + +std::vector CircleAddNSummaryBuilder::get_input_names(const luci::CircleNode *node) +{ + return std::vector(node->arity(), "inputs"); +} + +std::vector CircleArgMaxSummaryBuilder::get_input_names(const luci::CircleNode *) +{ + return {"input", "dimension"}; +} + +void CircleArgMaxSummaryBuilder::build_attributes(const luci::CircleNode *node, + locop::NodeSummary &s) +{ + auto argmax = loco::must_cast(node); + s.args().append("output_type", to_str(argmax->output_type())); +} + +std::vector CircleArgMinSummaryBuilder::get_input_names(const luci::CircleNode *) +{ + return {"input", "dimension"}; +} + +void CircleArgMinSummaryBuilder::build_attributes(const luci::CircleNode *node, + locop::NodeSummary &s) +{ + auto argmin = loco::must_cast(node); + s.args().append("output_type", to_str(argmin->output_type())); +} + +bool CircleAveragePool2DSummaryBuilder::validate(const luci::CircleNode *node) +{ + auto avgpool = loco::must_cast(node); + if (avgpool->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return false; + if (avgpool->padding() == luci::Padding::UNDEFINED) + return false; + + return true; +} + +std::vector +CircleAveragePool2DSummaryBuilder::get_input_names(const luci::CircleNode *) +{ + return {"value"}; +} + +void CircleAveragePool2DSummaryBuilder::build_attributes(const luci::CircleNode *node, + locop::NodeSummary &s) +{ + auto avgpool = loco::must_cast(node); + s.args().append("filter(h,w)", to_str(avgpool->filter())); + s.args().append("stride(h,w)", to_str(avgpool->stride())); + s.args().append("padding", to_str(avgpool->padding())); + s.args().append("fused_activation_function", to_str(avgpool->fusedActivationFunction())); +} + +void CircleBatchMatMulSummaryBuilder::build_attributes(const luci::CircleNode *node, + locop::NodeSummary &s) +{ + auto batchmatmul = loco::must_cast(node); + s.args().append("adj_x", to_str(batchmatmul->adj_x())); + s.args().append("adj_y", to_str(batchmatmul->adj_y())); +} + +std::vector +CircleBatchToSpaceNDSummaryBuilder::get_input_names(const luci::CircleNode *) +{ + return {"input", "block_shape", "crops"}; +} + +bool CircleBCQFullyConnectedSummaryBuilder::validate(const luci::CircleNode *node) +{ + auto bcq_fc = loco::must_cast(node); + if (bcq_fc->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return false; + + return true; +} + +std::vector +CircleBCQFullyConnectedSummaryBuilder::get_input_names(const luci::CircleNode *) +{ + return {"input", "weights_scales", "weights_binary", "bias", "weights_clusters"}; +} + +void CircleBCQFullyConnectedSummaryBuilder::build_attributes(const luci::CircleNode *node, + locop::NodeSummary &s) +{ + auto bcq_fc = loco::must_cast(node); + s.args().append("fused_activation_function", to_str(bcq_fc->fusedActivationFunction())); + s.args().append("weights_hidden_size", std::to_string(bcq_fc->weights_hidden_size())); +} + +std::vector CircleBCQGatherSummaryBuilder::get_input_names(const luci::CircleNode *) +{ + return {"input_scales", "input_binary", "indices", "input_clusters"}; +} + +void CircleBCQGatherSummaryBuilder::build_attributes(const luci::CircleNode *node, + locop::NodeSummary &s) +{ + auto bcq_gather = loco::must_cast(node); + s.args().append("axis", std::to_string(bcq_gather->axis())); + s.args().append("input_hidden_size", std::to_string(bcq_gather->input_hidden_size())); +} + +std::vector +CircleBidirectionalSequenceLSTMSummaryBuilder::get_input_names(const luci::CircleNode *) +{ + return {"input", + "fw_input_to_input_weights", + "fw_input_to_forget_weights", + "fw_input_to_cell_weights", + "fw_input_to_output_weights", + "fw_recurrent_to_input_weights", + "fw_recurrent_to_forget_weights", + "fw_recurrent_to_cell_weights", + "fw_recurrent_to_output_weights", + "fw_cell_to_input_weights", + "fw_cell_to_forget_weights", + "fw_cell_to_output_weights", + "fw_input_gate_bias", + "fw_forget_gate_bias", + "fw_cell_gate_bias", + "fw_output_gate_bias", + "fw_projection_weights", + "fw_projection_bias", + "bw_input_to_input_weights", + "bw_input_to_forget_weights", + "bw_input_to_cell_weights", + "bw_input_to_output_weights", + "bw_recurrent_to_input_weights", + "bw_recurrent_to_forget_weights", + "bw_recurrent_to_cell_weights", + "bw_recurrent_to_output_weights", + "bw_cell_to_input_weights", + "bw_cell_to_forget_weights", + "bw_cell_to_output_weights", + "bw_input_gate_bias", + "bw_forget_gate_bias", + "bw_cell_gate_bias", + "bw_output_gate_bias", + "bw_projection_weights", + "bw_projection_bias", + "fw_activation_state", + "fw_cell_state", + "bw_activation_state", + "bw_cell_state", + "auxillary_input", + "fw_auxillary_input_to_input_weights", + "fw_auxillary_input_to_forget_weights", + "fw_auxillary_input_to_cell_weights", + "fw_auxillary_input_to_output_weights", + "bw_auxillary_input_to_input_weights", + "bw_auxillary_input_to_forget_weights", + "bw_auxillary_input_to_cell_weights", + "bw_auxillary_input_to_output_weights"}; +} + +void CircleBidirectionalSequenceLSTMSummaryBuilder::build_attributes(const luci::CircleNode *node, + locop::NodeSummary &s) +{ + auto lstm = loco::must_cast(node); + s.args().append("cell_clip", to_str(lstm->cell_clip())); + s.args().append("proj_clip", to_str(lstm->proj_clip())); + s.args().append("merge_outputs", to_str(lstm->merge_outputs())); + s.args().append("time_major", to_str(lstm->time_major())); + s.args().append("asymmetric_quantize_inputs", to_str(lstm->asymmetric_quantize_inputs())); +} + +std::vector CircleCastSummaryBuilder::get_input_names(const luci::CircleNode *) +{ + return {"x"}; +} + +void CircleCastSummaryBuilder::build_attributes(const luci::CircleNode *node, locop::NodeSummary &s) +{ + auto cast = loco::must_cast(node); + s.args().append("in_data_type", to_str(cast->in_data_type())); + s.args().append("out_data_type", to_str(cast->out_data_type())); +} + +bool CircleConcatenationSummaryBuilder::validate(const luci::CircleNode *node) +{ + auto concat = loco::must_cast(node); + if (concat->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return false; + + return true; +} + +std::vector +CircleConcatenationSummaryBuilder::get_input_names(const luci::CircleNode *node) +{ + return std::vector(node->arity(), "values"); +} + +void CircleConcatenationSummaryBuilder::build_attributes(const luci::CircleNode *node, + locop::NodeSummary &s) +{ + auto concat = loco::must_cast(node); + s.args().append("axis", std::to_string(concat->axis())); + s.args().append("fused_activation_function", to_str(concat->fusedActivationFunction())); +} + +void CircleConstSummaryBuilder::update_status(locop::NodeSummary &s) +{ + s.state(locop::NodeDesc::State::PartiallyKnown); +} + +bool CircleConv2DSummaryBuilder::validate(const luci::CircleNode *node) +{ + auto conv2d = loco::must_cast(node); + if (conv2d->fusedActivationFunction() == luci::FusedActFunc::UNDEFINED) + return false; + if (conv2d->padding() == luci::Padding::UNDEFINED) + return false; + + return true; +} + +std::vector CircleConv2DSummaryBuilder::get_input_names(const luci::CircleNode *) +{ + return {"input", "filter", "bias"}; +} + +void CircleConv2DSummaryBuilder::build_attributes(const luci::CircleNode *node, + locop::NodeSummary &s) +{ + auto conv2d = loco::must_cast(node); + s.args().append("stride(h,w)", to_str(conv2d->stride())); + s.args().append("dilation(h,w)", to_str(conv2d->dilation())); + s.args().append("padding", to_str(conv2d->padding())); + s.args().append("fused_activation_function", to_str(conv2d->fusedActivationFunction())); +} + +std::vector CircleCustomSummaryBuilder::get_input_names(const luci::CircleNode *node) +{ + auto input_names = std::vector(); + for (uint32_t i = 0; i < node->arity(); ++i) + input_names.push_back("input" + std::to_string(i)); + return input_names; +} + +void CircleCustomSummaryBuilder::build_attributes(const luci::CircleNode *node, + locop::NodeSummary &s) +{ + auto custom = loco::must_cast(node); + s.args().append("custom_code", custom->custom_code()); +} + +} // namespace luci diff --git a/compiler/luci/logex/src/CircleNodeSummaryBuilders.h b/compiler/luci/logex/src/CircleNodeSummaryBuilders.h new file mode 100644 index 00000000000..f1cd36eada5 --- /dev/null +++ b/compiler/luci/logex/src/CircleNodeSummaryBuilders.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2022 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_LOGEX_CIRCLE_NODE_SUMMARY_BUILDERS__ +#define __LUCI_LOGEX_CIRCLE_NODE_SUMMARY_BUILDERS__ + +#include "CircleNodeSummaryBuilder.h" + +#include + +#include +#include + +namespace luci +{ + +class CircleNodeWithXSummaryBuilder : public CircleNodeSummaryBuilder +{ +private: + std::vector get_input_names(const luci::CircleNode *); +}; + +class CircleNodeWithINPUTSummaryBuilder : public CircleNodeSummaryBuilder +{ +private: + std::vector get_input_names(const luci::CircleNode *); +}; + +class CircleNodeWithXYSummaryBuilder : public CircleNodeSummaryBuilder +{ +private: + std::vector get_input_names(const luci::CircleNode *); +}; + +} // namespace luci + +namespace luci +{ + +class CircleAbsSummaryBuilder final : public CircleNodeWithXSummaryBuilder +{ +}; + +class CircleAddSummaryBuilder final : public CircleNodeWithXYSummaryBuilder +{ +private: + bool validate(const luci::CircleNode *node); + void build_attributes(const luci::CircleNode *node, locop::NodeSummary &s); +}; + +class CircleAddNSummaryBuilder final : public CircleNodeSummaryBuilder +{ +private: + std::vector get_input_names(const luci::CircleNode *node); +}; + +class CircleArgMaxSummaryBuilder final : public CircleNodeSummaryBuilder +{ +private: + std::vector get_input_names(const luci::CircleNode *); + void build_attributes(const luci::CircleNode *node, locop::NodeSummary &s); +}; + +class CircleArgMinSummaryBuilder final : public CircleNodeSummaryBuilder +{ +private: + std::vector get_input_names(const luci::CircleNode *); + void build_attributes(const luci::CircleNode *node, locop::NodeSummary &s); +}; + +class CircleAveragePool2DSummaryBuilder final : public CircleNodeSummaryBuilder +{ +private: + bool validate(const luci::CircleNode *node); + std::vector get_input_names(const luci::CircleNode *); + void build_attributes(const luci::CircleNode *node, locop::NodeSummary &s); +}; + +class CircleBatchMatMulSummaryBuilder final : public CircleNodeWithXYSummaryBuilder +{ +private: + void build_attributes(const luci::CircleNode *node, locop::NodeSummary &s); +}; + +class CircleBatchToSpaceNDSummaryBuilder final : public CircleNodeSummaryBuilder +{ +private: + std::vector get_input_names(const luci::CircleNode *); +}; + +class CircleBCQFullyConnectedSummaryBuilder final : public CircleNodeSummaryBuilder +{ +private: + bool validate(const luci::CircleNode *node); + std::vector get_input_names(const luci::CircleNode *); + void build_attributes(const luci::CircleNode *node, locop::NodeSummary &s); +}; + +class CircleBCQGatherSummaryBuilder final : public CircleNodeSummaryBuilder +{ +private: + std::vector get_input_names(const luci::CircleNode *); + void build_attributes(const luci::CircleNode *node, locop::NodeSummary &s); +}; + +class CircleBidirectionalSequenceLSTMSummaryBuilder final : public CircleNodeSummaryBuilder +{ +private: + std::vector get_input_names(const luci::CircleNode *); + void build_attributes(const luci::CircleNode *node, locop::NodeSummary &s); +}; + +class CircleBidirectionalSequenceLSTMOutSummaryBuilder final + : public CircleNodeWithINPUTSummaryBuilder +{ +}; + +class CircleCastSummaryBuilder final : public CircleNodeSummaryBuilder +{ +private: + std::vector get_input_names(const luci::CircleNode *); + void build_attributes(const luci::CircleNode *node, locop::NodeSummary &s); +}; + +class CircleCeilSummaryBuilder final : public CircleNodeWithXSummaryBuilder +{ +}; + +class CircleConcatenationSummaryBuilder final : public CircleNodeSummaryBuilder +{ +private: + bool validate(const luci::CircleNode *node); + std::vector get_input_names(const luci::CircleNode *node); + void build_attributes(const luci::CircleNode *node, locop::NodeSummary &s); +}; + +class CircleConstSummaryBuilder final : public CircleNodeSummaryBuilder +{ +private: + void update_status(locop::NodeSummary &s); +}; + +class CircleConv2DSummaryBuilder final : public CircleNodeSummaryBuilder +{ +private: + bool validate(const luci::CircleNode *node); + std::vector get_input_names(const luci::CircleNode *); + void build_attributes(const luci::CircleNode *node, locop::NodeSummary &s); +}; + +class CircleCosSummaryBuilder final : public CircleNodeWithXSummaryBuilder +{ +}; + +class CircleCustomSummaryBuilder final : public CircleNodeSummaryBuilder +{ +private: + std::vector get_input_names(const luci::CircleNode *node); + void build_attributes(const luci::CircleNode *node, locop::NodeSummary &s); +}; + +class CircleCustomOutSummaryBuilder final : public CircleNodeWithINPUTSummaryBuilder +{ +}; + +} // namespace luci + +#endif // __LUCI_LOGEX_CIRCLE_NODE_SUMMARY_BUILDERS__ diff --git a/compiler/luci/logex/src/FormattedGraph.cpp b/compiler/luci/logex/src/FormattedGraph.cpp index 9a4451c5b29..560ad5a5852 100644 --- a/compiler/luci/logex/src/FormattedGraph.cpp +++ b/compiler/luci/logex/src/FormattedGraph.cpp @@ -251,192 +251,6 @@ bool use_ido(const locop::SymbolTable *tbl, const CIRCLENODE *node, locop::NodeS return true; } -bool summary_node(const locop::SymbolTable *tbl, const luci::CircleAddN *node, - locop::NodeSummary &s) -{ - for (uint32_t i = 0; i < node->arity(); ++i) - s.args().append("inputs", tbl->lookup(node->inputs(i))); - s.state(locop::NodeSummary::State::Complete); - return true; -} - -bool summary_node(const locop::SymbolTable *tbl, const luci::CircleAveragePool2D *node, - locop::NodeSummary &s) -{ - assert(node->fusedActivationFunction() != luci::FusedActFunc::UNDEFINED); - - s.args().append("value", tbl->lookup(node->value())); - s.args().append("filter(h,w)", to_str(node->filter())); - s.args().append("stride(h,w)", to_str(node->stride())); - s.args().append("padding", to_str(node->padding())); - s.args().append("fused", to_str(node->fusedActivationFunction())); - s.state(locop::NodeSummary::State::Complete); - return true; -} - -bool summary_node(const locop::SymbolTable *tbl, const luci::CircleBatchMatMul *node, - locop::NodeSummary &s) -{ - s.args().append("x", tbl->lookup(node->x())); - s.args().append("y", tbl->lookup(node->y())); - s.args().append("adj_x", to_str(node->adj_x())); - s.args().append("adj_y", to_str(node->adj_y())); - s.state(locop::NodeSummary::State::Complete); - return true; -} - -bool summary_node(const locop::SymbolTable *tbl, const luci::CircleBatchToSpaceND *node, - locop::NodeSummary &s) -{ - s.args().append("input", tbl->lookup(node->input())); - s.args().append("block_shape", tbl->lookup(node->block_shape())); - s.args().append("crops", tbl->lookup(node->crops())); - s.state(locop::NodeSummary::State::Complete); - return true; -} - -bool summary_node(const locop::SymbolTable *tbl, const luci::CircleBidirectionalSequenceLSTM *node, - locop::NodeSummary &s) -{ - s.args().append("input", tbl->lookup(node->input())); - - s.args().append("fw_input_to_input_weights", tbl->lookup(node->fw_input_to_input_weights())); - s.args().append("fw_input_to_forget_weights", tbl->lookup(node->fw_input_to_forget_weights())); - s.args().append("fw_input_to_cell_weights", tbl->lookup(node->fw_input_to_cell_weights())); - s.args().append("fw_input_to_output_weights", tbl->lookup(node->fw_input_to_output_weights())); - - s.args().append("fw_recurrent_to_input_weights", - tbl->lookup(node->fw_recurrent_to_input_weights())); - s.args().append("fw_recurrent_to_forget_weights", - tbl->lookup(node->fw_recurrent_to_forget_weights())); - s.args().append("fw_recurrent_to_cell_weights", - tbl->lookup(node->fw_recurrent_to_cell_weights())); - s.args().append("fw_recurrent_to_output_weights", - tbl->lookup(node->fw_recurrent_to_output_weights())); - - s.args().append("fw_cell_to_input_weights", tbl->lookup(node->fw_cell_to_input_weights())); - s.args().append("fw_cell_to_forget_weights", tbl->lookup(node->fw_cell_to_forget_weights())); - s.args().append("fw_cell_to_output_weights", tbl->lookup(node->fw_cell_to_output_weights())); - - s.args().append("fw_input_gate_bias", tbl->lookup(node->fw_input_gate_bias())); - s.args().append("fw_forget_gate_bias", tbl->lookup(node->fw_forget_gate_bias())); - s.args().append("fw_cell_gate_bias", tbl->lookup(node->fw_cell_gate_bias())); - s.args().append("fw_output_gate_bias", tbl->lookup(node->fw_output_gate_bias())); - - s.args().append("fw_projection_weights", tbl->lookup(node->fw_projection_weights())); - s.args().append("fw_projection_bias", tbl->lookup(node->fw_projection_bias())); - - s.args().append("bw_input_to_input_weights", tbl->lookup(node->bw_input_to_input_weights())); - s.args().append("bw_input_to_forget_weights", tbl->lookup(node->bw_input_to_forget_weights())); - s.args().append("bw_input_to_cell_weights", tbl->lookup(node->bw_input_to_cell_weights())); - s.args().append("bw_input_to_output_weights", tbl->lookup(node->bw_input_to_output_weights())); - - s.args().append("bw_recurrent_to_input_weights", - tbl->lookup(node->bw_recurrent_to_input_weights())); - s.args().append("bw_recurrent_to_forget_weights", - tbl->lookup(node->bw_recurrent_to_forget_weights())); - s.args().append("bw_recurrent_to_cell_weights", - tbl->lookup(node->bw_recurrent_to_cell_weights())); - s.args().append("bw_recurrent_to_output_weights", - tbl->lookup(node->bw_recurrent_to_output_weights())); - - s.args().append("bw_cell_to_input_weights", tbl->lookup(node->bw_cell_to_input_weights())); - s.args().append("bw_cell_to_forget_weights", tbl->lookup(node->bw_cell_to_forget_weights())); - s.args().append("bw_cell_to_output_weights", tbl->lookup(node->bw_cell_to_output_weights())); - - s.args().append("bw_input_gate_bias", tbl->lookup(node->bw_input_gate_bias())); - s.args().append("bw_forget_gate_bias", tbl->lookup(node->bw_forget_gate_bias())); - s.args().append("bw_cell_gate_bias", tbl->lookup(node->bw_cell_gate_bias())); - s.args().append("bw_output_gate_bias", tbl->lookup(node->bw_output_gate_bias())); - - s.args().append("bw_projection_weights", tbl->lookup(node->bw_projection_weights())); - s.args().append("bw_projection_bias", tbl->lookup(node->bw_projection_bias())); - - s.args().append("fw_activation_state", tbl->lookup(node->fw_activation_state())); - s.args().append("fw_cell_state", tbl->lookup(node->fw_cell_state())); - s.args().append("bw_activation_state", tbl->lookup(node->bw_activation_state())); - s.args().append("bw_cell_state", tbl->lookup(node->bw_cell_state())); - - s.args().append("auxillary_input", tbl->lookup(node->auxillary_input())); - s.args().append("fw_auxillary_input_to_input_weights", - tbl->lookup(node->fw_auxillary_input_to_input_weights())); - s.args().append("fw_auxillary_input_to_forget_weights", - tbl->lookup(node->fw_auxillary_input_to_forget_weights())); - s.args().append("fw_auxillary_input_to_cell_weights", - tbl->lookup(node->fw_auxillary_input_to_cell_weights())); - s.args().append("fw_auxillary_input_to_output_weights", - tbl->lookup(node->fw_auxillary_input_to_output_weights())); - s.args().append("bw_auxillary_input_to_input_weights", - tbl->lookup(node->bw_auxillary_input_to_input_weights())); - s.args().append("bw_auxillary_input_to_forget_weights", - tbl->lookup(node->bw_auxillary_input_to_forget_weights())); - s.args().append("bw_auxillary_input_to_cell_weights", - tbl->lookup(node->bw_auxillary_input_to_cell_weights())); - s.args().append("bw_auxillary_input_to_output_weights", - tbl->lookup(node->bw_auxillary_input_to_output_weights())); - - s.args().append("cell_clip", to_str(node->cell_clip())); - s.args().append("proj_clip", to_str(node->proj_clip())); - s.args().append("merge_outputs", to_str(node->merge_outputs())); - s.args().append("time_major", to_str(node->time_major())); - s.args().append("asymmetric_quantize_inputs", to_str(node->asymmetric_quantize_inputs())); - - s.state(locop::NodeSummary::State::Complete); - return true; -} - -bool summary_node(const locop::SymbolTable *tbl, const luci::CircleCast *node, - locop::NodeSummary &s) -{ - s.args().append("x", tbl->lookup(node->x())); - s.args().append("in_data_type", to_str(node->in_data_type())); - s.args().append("out_data_type", to_str(node->out_data_type())); - s.state(locop::NodeSummary::State::Complete); - return true; -} - -bool summary_node(const locop::SymbolTable *tbl, const luci::CircleConcatenation *node, - locop::NodeSummary &s) -{ - assert(node->fusedActivationFunction() != luci::FusedActFunc::UNDEFINED); - - for (uint32_t i = 0; i < node->numValues(); ++i) - s.args().append("values", tbl->lookup(node->values(i))); - s.args().append("axis", pepper::str(node->axis())); - s.args().append("fused", to_str(node->fusedActivationFunction())); - s.state(locop::NodeSummary::State::Complete); - return true; -} - -bool summary_node(const locop::SymbolTable *tbl, const luci::CircleConv2D *node, - locop::NodeSummary &s) -{ - assert(node->fusedActivationFunction() != luci::FusedActFunc::UNDEFINED); - assert(node->padding() != luci::Padding::UNDEFINED); - - s.args().append("input", tbl->lookup(node->input())); - s.args().append("filter", tbl->lookup(node->filter())); - s.args().append("bias", tbl->lookup(node->bias())); - s.args().append("stride(h,w)", to_str(node->stride())); - s.args().append("dilation(h,w)", to_str(node->dilation())); - s.args().append("padding", to_str(node->padding())); - s.args().append("fused", to_str(node->fusedActivationFunction())); - s.state(locop::NodeSummary::State::Complete); - return true; -} - -bool summary_node(const locop::SymbolTable *tbl, const luci::CircleCustom *node, - locop::NodeSummary &s) -{ - for (uint32_t i = 0; i < node->numInputs(); i++) - { - s.args().append("input" + std::to_string(i), tbl->lookup(node->inputs(i))); - } - s.args().append("custom_code", node->custom_code()); - s.state(locop::NodeSummary::State::Complete); - return true; -} - bool summary_node(const locop::SymbolTable *tbl, const luci::CircleDepthToSpace *node, locop::NodeSummary &s) { @@ -1172,7 +986,6 @@ bool summary_node(const locop::SymbolTable *tbl, const luci::CircleInstanceNorm // SummaryBuilderLet type enum class SB { - ABC, DEF, GHIJ, KLMN, @@ -1187,33 +1000,6 @@ template class SummaryBuilderLet; #define IMPLEMENT(CLASS) bool summary(const CLASS *, locop::NodeSummary &) const final; -template <> class SummaryBuilderLet final : public CircleNodeSummaryBuilderBase -{ -public: - SummaryBuilderLet(const locop::SymbolTable *tbl) : CircleNodeSummaryBuilderBase(tbl) - { - // DO NOTHING - } - -private: - IMPLEMENT(luci::CircleAbs) - IMPLEMENT(luci::CircleAdd) - IMPLEMENT(luci::CircleAddN) - IMPLEMENT(luci::CircleArgMax) - IMPLEMENT(luci::CircleArgMin) - IMPLEMENT(luci::CircleAveragePool2D) - IMPLEMENT(luci::CircleBatchMatMul) - IMPLEMENT(luci::CircleBatchToSpaceND) - IMPLEMENT(luci::CircleBidirectionalSequenceLSTM) - IMPLEMENT(luci::CircleCast) - IMPLEMENT(luci::CircleCeil) - IMPLEMENT(luci::CircleConcatenation) - IMPLEMENT(luci::CircleConst) - IMPLEMENT(luci::CircleConv2D) - IMPLEMENT(luci::CircleCos) - IMPLEMENT(luci::CircleCustom) -}; - template <> class SummaryBuilderLet final : public CircleNodeSummaryBuilderBase { public: @@ -1454,96 +1240,6 @@ bool CircleNodeSummaryBuilderBase::build(const loco::Node *node, locop::NodeSumm return false; } -bool SummaryBuilderLet::summary(const luci::CircleAbs *node, locop::NodeSummary &s) const -{ - return use_x(tbl(), node, s); -} - -bool SummaryBuilderLet::summary(const luci::CircleAdd *node, locop::NodeSummary &s) const -{ - return use_xy_act(tbl(), node, s); -} - -bool SummaryBuilderLet::summary(const luci::CircleAddN *node, locop::NodeSummary &s) const -{ - return summary_node(tbl(), node, s); -} - -bool SummaryBuilderLet::summary(const luci::CircleArgMax *node, - locop::NodeSummary &s) const -{ - return use_ido(tbl(), node, s); -} - -bool SummaryBuilderLet::summary(const luci::CircleArgMin *node, - locop::NodeSummary &s) const -{ - return use_ido(tbl(), node, s); -} - -bool SummaryBuilderLet::summary(const luci::CircleAveragePool2D *node, - locop::NodeSummary &s) const -{ - return summary_node(tbl(), node, s); -} - -bool SummaryBuilderLet::summary(const luci::CircleBatchMatMul *node, - locop::NodeSummary &s) const -{ - return summary_node(tbl(), node, s); -} - -bool SummaryBuilderLet::summary(const luci::CircleBatchToSpaceND *node, - locop::NodeSummary &s) const -{ - return summary_node(tbl(), node, s); -} - -bool SummaryBuilderLet::summary(const luci::CircleBidirectionalSequenceLSTM *node, - locop::NodeSummary &s) const -{ - return summary_node(tbl(), node, s); -} - -bool SummaryBuilderLet::summary(const luci::CircleCast *node, locop::NodeSummary &s) const -{ - return summary_node(tbl(), node, s); -} - -bool SummaryBuilderLet::summary(const luci::CircleCeil *node, locop::NodeSummary &s) const -{ - return use_x(tbl(), node, s); -} - -bool SummaryBuilderLet::summary(const luci::CircleConcatenation *node, - locop::NodeSummary &s) const -{ - return summary_node(tbl(), node, s); -} - -bool SummaryBuilderLet::summary(const luci::CircleConst *, locop::NodeSummary &s) const -{ - s.state(locop::NodeSummary::State::PartiallyKnown); - return true; -} - -bool SummaryBuilderLet::summary(const luci::CircleConv2D *node, - locop::NodeSummary &s) const -{ - return summary_node(tbl(), node, s); -} - -bool SummaryBuilderLet::summary(const luci::CircleCos *node, locop::NodeSummary &s) const -{ - return use_x(tbl(), node, s); -} - -bool SummaryBuilderLet::summary(const luci::CircleCustom *node, - locop::NodeSummary &s) const -{ - return summary_node(tbl(), node, s); -} - bool SummaryBuilderLet::summary(const luci::CircleDepthToSpace *node, locop::NodeSummary &s) const { @@ -2247,7 +1943,6 @@ bool NodeSummaryBuilder::build(const loco::Node *node, locop::NodeSummary &s) co } while (false) // TODO Replace with CircleNodeSummaryBuilder and then remove these - BUILD_GRP(ABC); BUILD_GRP(DEF); BUILD_GRP(GHIJ); BUILD_GRP(KLMN);