From 301d6b50e3733e5e8764e3596e393e32c404a3b5 Mon Sep 17 00:00:00 2001 From: Gleb Kazantaev Date: Wed, 19 Aug 2020 18:55:11 +0300 Subject: [PATCH] Moved AlgebraicSimplification and NopElimination passes to IE (#1859) * Moved AlgebraicSimplification and NopElimination passes to IE * Fixed headerfiles --- .../algebraic_simplification.hpp | 25 +- .../common_optimizations/nop_elimination.hpp | 26 ++ .../algebraic_simplification.cpp | 134 +++------- .../common_optimizations.cpp | 4 +- .../common_optimizations}/nop_elimination.cpp | 242 ++++++------------ .../algebraic_simplification.cpp | 182 ++++--------- .../transformations}/nop_elimination.cpp | 153 ++++------- .../transpose_to_reshape_test.cpp | 2 +- .../common_test_utils/ngraph_test_utils.cpp | 3 + .../common_test_utils/ngraph_test_utils.hpp | 33 +++ .../include/ngraph/pass/nop_elimination.hpp | 31 --- ngraph/test/CMakeLists.txt | 1 - 12 files changed, 302 insertions(+), 534 deletions(-) rename {ngraph/core/include/ngraph/pass => inference-engine/src/transformations/include/transformations/common_optimizations}/algebraic_simplification.hpp (67%) create mode 100644 inference-engine/src/transformations/include/transformations/common_optimizations/nop_elimination.hpp rename {ngraph/core/src/pass => inference-engine/src/transformations/src/transformations/common_optimizations}/algebraic_simplification.cpp (80%) rename {ngraph/core/src/pass => inference-engine/src/transformations/src/transformations/common_optimizations}/nop_elimination.cpp (77%) rename {ngraph/test => inference-engine/tests/functional/inference_engine/transformations}/algebraic_simplification.cpp (86%) rename {ngraph/test => inference-engine/tests/functional/inference_engine/transformations}/nop_elimination.cpp (90%) delete mode 100644 ngraph/core/include/ngraph/pass/nop_elimination.hpp diff --git a/ngraph/core/include/ngraph/pass/algebraic_simplification.hpp b/inference-engine/src/transformations/include/transformations/common_optimizations/algebraic_simplification.hpp similarity index 67% rename from ngraph/core/include/ngraph/pass/algebraic_simplification.hpp rename to inference-engine/src/transformations/include/transformations/common_optimizations/algebraic_simplification.hpp index e6ebf878569..56e5b62f415 100644 --- a/ngraph/core/include/ngraph/pass/algebraic_simplification.hpp +++ b/inference-engine/src/transformations/include/transformations/common_optimizations/algebraic_simplification.hpp @@ -16,19 +16,20 @@ #pragma once -#include "ngraph/pass/pass.hpp" -#include "ngraph/util.hpp" +#include +#include -namespace ngraph -{ - namespace pass - { - class AlgebraicSimplification; - } -} +#include -class NGRAPH_API ngraph::pass::AlgebraicSimplification : public FunctionPass -{ +namespace ngraph { +namespace pass { + +class TRANSFORMATIONS_API AlgebraicSimplification; + +} // namespace pass +} // namespace ngraph + +class ngraph::pass::AlgebraicSimplification : public FunctionPass { public: - virtual bool run_on_function(std::shared_ptr f); + bool run_on_function(std::shared_ptr f) override; }; diff --git a/inference-engine/src/transformations/include/transformations/common_optimizations/nop_elimination.hpp b/inference-engine/src/transformations/include/transformations/common_optimizations/nop_elimination.hpp new file mode 100644 index 00000000000..ccf61563ae9 --- /dev/null +++ b/inference-engine/src/transformations/include/transformations/common_optimizations/nop_elimination.hpp @@ -0,0 +1,26 @@ +// Copyright (C) 2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include + +#include + +#include +#include + +namespace ngraph { +namespace pass { + +class TRANSFORMATIONS_API NopElimination; + +} // namespace pass +} // namespace ngraph + +class ngraph::pass::NopElimination: public ngraph::pass::FunctionPass { +public: + bool run_on_function(std::shared_ptr) override; +}; diff --git a/ngraph/core/src/pass/algebraic_simplification.cpp b/inference-engine/src/transformations/src/transformations/common_optimizations/algebraic_simplification.cpp similarity index 80% rename from ngraph/core/src/pass/algebraic_simplification.cpp rename to inference-engine/src/transformations/src/transformations/common_optimizations/algebraic_simplification.cpp index 7baca2ed14c..91d78f55a1a 100644 --- a/ngraph/core/src/pass/algebraic_simplification.cpp +++ b/inference-engine/src/transformations/src/transformations/common_optimizations/algebraic_simplification.cpp @@ -18,61 +18,36 @@ #include #include -#include "algebraic_simplification.hpp" -#include "ngraph/axis_vector.hpp" -#include "ngraph/graph_util.hpp" -#include "ngraph/log.hpp" -#include "ngraph/op/add.hpp" -#include "ngraph/op/broadcast.hpp" -#include "ngraph/op/concat.hpp" -#include "ngraph/op/constant.hpp" -#include "ngraph/op/divide.hpp" -#include "ngraph/op/exp.hpp" -#include "ngraph/op/gather.hpp" -#include "ngraph/op/log.hpp" -#include "ngraph/op/multiply.hpp" -#include "ngraph/op/product.hpp" -#include "ngraph/op/reshape.hpp" -#include "ngraph/op/shape_of.hpp" -#include "ngraph/op/slice.hpp" -#include "ngraph/op/subtract.hpp" -#include "ngraph/op/sum.hpp" -#include "ngraph/op/transpose.hpp" -#include "ngraph/op/util/op_types.hpp" -#include "ngraph/opsets/opset2.hpp" -#include "ngraph/opsets/opset3.hpp" -#include "ngraph/pattern/matcher.hpp" -#include "ngraph/rt_info.hpp" -#include "ngraph/util.hpp" +#include "transformations/common_optimizations/algebraic_simplification.hpp" + +#include +#include +#include +#include using namespace std; using namespace ngraph; //`simplify_gather`, optimizes gather if Gather is gathering the // whole input tensor -static bool simplify_gather(std::shared_ptr node) -{ - if (auto gather = as_type_ptr(node)) - { +static bool simplify_gather(std::shared_ptr node) { + if (auto gather = as_type_ptr(node)) { // check if we are gathering the whole input auto data = gather->input_value(0); auto indices = gather->input_value(1); // we need to know data and indices shape to infer if gather is Nop - if (data.get_partial_shape().is_dynamic() || indices.get_partial_shape().is_dynamic()) - { + if (data.get_partial_shape().is_dynamic() || indices.get_partial_shape().is_dynamic()) { return false; } // if rank of data and gather output dont match, we will skip - if (data.get_shape().size() != node->get_shape().size()) - { + if (data.get_shape().size() != node->get_shape().size()) { return false; } auto axis = gather->get_axis(); - if (axis == opset3::Gather::AXIS_NOT_SET_VALUE) - { + if (axis == opset3::Gather::AXIS_NOT_SET_VALUE) { NGRAPH_DEBUG << "axis value not set"; return false; } @@ -82,8 +57,7 @@ static bool simplify_gather(std::shared_ptr node) // gathering the whole input tensor, so we can optimize this // op has Nop - if (data.get_shape()[axis] == 1 && data.get_shape() == node->get_shape()) - { + if (data.get_shape()[axis] == 1 && data.get_shape() == node->get_shape()) { return replace_output_update_name(gather->output(0), gather->input_value(0)); } @@ -95,18 +69,14 @@ static bool simplify_gather(std::shared_ptr node) // check if the indices is constant auto constant_indices = as_type_ptr(gather->input_value(1).get_node_shared_ptr()); - if (!constant_indices) - { + if (!constant_indices) { return false; - } - else - { + } else { // if ref_inidices == indices, we are capturing the // entire input tensor std::vector ref_indices(data.get_shape()[axis], 0); std::iota(ref_indices.begin(), ref_indices.end(), 0); - if (ref_indices == constant_indices->cast_vector()) - { + if (ref_indices == constant_indices->cast_vector()) { return replace_output_update_name(gather->output(0), gather->input_value(0)); } } @@ -116,19 +86,16 @@ static bool simplify_gather(std::shared_ptr node) // optimizes `gather->shapeof` into `shapeof->gather` for 0D indices // other cases into Concat of shapeof/gather(data) + shapeof(indices) -static bool simplify_gather_shapeof(shared_ptr node) -{ +static bool simplify_gather_shapeof(shared_ptr node) { auto gather = as_type_ptr(node->input_value(0).get_node_shared_ptr()); - if (!gather) - { + if (!gather) { return false; } auto gather_in_rank = gather->get_input_partial_shape(0).rank(); auto indices_rank = gather->get_input_partial_shape(1).rank(); auto axis = gather->get_axis(); if (gather_in_rank.is_dynamic() || indices_rank.is_dynamic() || - axis == opset3::Gather::AXIS_NOT_SET_VALUE) - { + axis == opset3::Gather::AXIS_NOT_SET_VALUE) { NGRAPH_DEBUG << gather << " cannot simplify gather->shapeof"; return false; } @@ -138,20 +105,16 @@ static bool simplify_gather_shapeof(shared_ptr node) auto new_shapeof = make_shared(gather->input_value(0)); new_ops.push_back(new_shapeof); std::shared_ptr replace_op; - if (indices_rank.get_length() == 0) - { + if (indices_rank.get_length() == 0) { std::vector vi(gather_in_rank.get_length()); std::iota(vi.begin(), vi.end(), 0); vi.erase(vi.begin() + axis); auto new_indices = opset3::Constant::create(element::i64, Shape{vi.size()}, vi); replace_op = make_shared(new_shapeof, new_indices, zero_axis); new_ops.push_back(replace_op); - } - else - { + } else { NodeVector concat_inputs; - if (axis > 0) - { + if (axis > 0) { std::vector vi(axis); std::iota(vi.begin(), vi.end(), 0); auto indices = opset3::Constant::create(element::i64, Shape{vi.size()}, vi); @@ -164,8 +127,7 @@ static bool simplify_gather_shapeof(shared_ptr node) concat_inputs.push_back(shapeof_indices); - if (gather_in_rank.get_length() - 1 > axis) - { + if (gather_in_rank.get_length() - 1 > axis) { std::vector vi(gather_in_rank.get_length() - (axis + 1)); std::iota(vi.begin(), vi.end(), axis + 1); auto indices = opset3::Constant::create(element::i64, Shape{vi.size()}, vi); @@ -182,20 +144,17 @@ static bool simplify_gather_shapeof(shared_ptr node) return true; } -static bool replace_transpose_with_reshape(shared_ptr transpose) -{ +static bool replace_transpose_with_reshape(shared_ptr transpose) { auto data = transpose->input_value(0); const auto input_shape = transpose->input(0).get_partial_shape(); - if (input_shape.rank().is_dynamic()) - { + if (input_shape.rank().is_dynamic()) { return false; } const auto input_shape_rank = input_shape.rank().get_length(); auto order = as_type_ptr(transpose->input_value(1).get_node_shared_ptr()); - if (!order) - { + if (!order) { return false; } @@ -203,12 +162,9 @@ static bool replace_transpose_with_reshape(shared_ptr transpose) // Check that transpose order without 1 dims has an ascending order int64_t last_dim(-1); - for (size_t i = 0; i < input_shape_rank; ++i) - { - if (input_shape[order_value[i]].is_dynamic() || input_shape[order_value[i]] != 1) - { - if (order_value[i] < last_dim) - { + for (size_t i = 0; i < input_shape_rank; ++i) { + if (input_shape[order_value[i]].is_dynamic() || input_shape[order_value[i]] != 1) { + if (order_value[i] < last_dim) { return false; } last_dim = order_value[i]; @@ -217,16 +173,13 @@ static bool replace_transpose_with_reshape(shared_ptr transpose) // Transpose operation can be removed if original transpose order is sorted // or dimension that changes their places equal to 1 - using DimensionToPosition = struct - { + using DimensionToPosition = struct { Dimension dim; size_t pos; }; std::vector dims; - for (size_t i = 0; i < input_shape_rank; ++i) - { - if (order_value[i] != i) - { + for (size_t i = 0; i < input_shape_rank; ++i) { + if (order_value[i] != i) { dims.push_back({input_shape[order_value[i]], i}); } } @@ -234,8 +187,7 @@ static bool replace_transpose_with_reshape(shared_ptr transpose) // If number of dimensions != 1 to move equal to 0 we can remove this Transpose if (count_if(dims.begin(), dims.end(), [](const DimensionToPosition& item) { return !(item.dim.is_static() && item.dim.get_length() == 1); - }) == 0) - { + }) == 0) { return replace_output_update_name(transpose->output(0), transpose->input_value(0)); } @@ -254,18 +206,14 @@ static bool replace_transpose_with_reshape(shared_ptr transpose) if (count_if(dims.begin(), dims.end(), [](const DimensionToPosition& item) { return item.dim.is_dynamic(); - }) < 2) - { + }) < 2) { vector reshape_value(input_shape_rank, 0); - for (const auto& item : dims) - { + for (const auto& item : dims) { reshape_value[item.pos] = item.dim.is_dynamic() ? -1 : item.dim.get_length(); } reshape_dim = opset3::Constant::create(element::i64, Shape{reshape_value.size()}, reshape_value); - } - else - { + } else { auto shape_of = make_shared(data); new_ops.push_back(shape_of); reshape_dim = make_shared( @@ -283,8 +231,7 @@ static bool replace_transpose_with_reshape(shared_ptr transpose) return true; } -bool pass::AlgebraicSimplification::run_on_function(shared_ptr f) -{ +bool pass::AlgebraicSimplification::run_on_function(shared_ptr f) { static const unordered_map)>> ops_to_simplifiers = {{opset3::Gather::type_info, simplify_gather}, {opset2::ShapeOf::type_info, simplify_gather_shapeof}, @@ -292,16 +239,13 @@ bool pass::AlgebraicSimplification::run_on_function(shared_ptr f) {opset3::Transpose::type_info, replace_transpose_with_reshape}}; bool replaced = false; - for (auto n : f->get_ordered_ops()) - { - if (op::is_output(n) || op::is_parameter(n)) - { + for (auto n : f->get_ordered_ops()) { + if (op::is_output(n) || op::is_parameter(n)) { continue; } auto eh = ops_to_simplifiers.find(n->get_type_info()); - if (eh != ops_to_simplifiers.end()) - { + if (eh != ops_to_simplifiers.end()) { replaced = eh->second(n) || replaced; } } diff --git a/inference-engine/src/transformations/src/transformations/common_optimizations/common_optimizations.cpp b/inference-engine/src/transformations/src/transformations/common_optimizations/common_optimizations.cpp index dbb283becf5..99a226aa6af 100644 --- a/inference-engine/src/transformations/src/transformations/common_optimizations/common_optimizations.cpp +++ b/inference-engine/src/transformations/src/transformations/common_optimizations/common_optimizations.cpp @@ -4,6 +4,8 @@ #include +#include "transformations/common_optimizations/algebraic_simplification.hpp" +#include "transformations/common_optimizations/nop_elimination.hpp" #include "transformations/common_optimizations/common_optimizations.hpp" #include "transformations/depth_to_space_fusion.hpp" #include "transformations/optimize_strided_slice.hpp" @@ -17,8 +19,6 @@ #include "transformations/hswish_fusion.hpp" #include -#include -#include #include bool ngraph::pass::CommonOptimizations::run_on_function(std::shared_ptr f) { diff --git a/ngraph/core/src/pass/nop_elimination.cpp b/inference-engine/src/transformations/src/transformations/common_optimizations/nop_elimination.cpp similarity index 77% rename from ngraph/core/src/pass/nop_elimination.cpp rename to inference-engine/src/transformations/src/transformations/common_optimizations/nop_elimination.cpp index 37d3a649bdf..014811ce050 100644 --- a/ngraph/core/src/pass/nop_elimination.cpp +++ b/inference-engine/src/transformations/src/transformations/common_optimizations/nop_elimination.cpp @@ -20,72 +20,48 @@ #include #include -#include "ngraph/graph_util.hpp" -#include "ngraph/log.hpp" -#include "ngraph/op/broadcast.hpp" -#include "ngraph/op/concat.hpp" -#include "ngraph/op/constant.hpp" -#include "ngraph/op/convert.hpp" -#include "ngraph/op/non_zero.hpp" -#include "ngraph/op/pad.hpp" -#include "ngraph/op/reshape.hpp" -#include "ngraph/op/shape_of.hpp" -#include "ngraph/op/slice.hpp" -#include "ngraph/op/squeeze.hpp" -#include "ngraph/op/stop_gradient.hpp" -#include "ngraph/op/sum.hpp" -#include "ngraph/op/unsqueeze.hpp" -#include "ngraph/op/util/op_types.hpp" -#include "ngraph/opsets/opset3.hpp" -#include "ngraph/util.hpp" -#include "nop_elimination.hpp" +#include +#include +#include +#include using namespace std; using namespace ngraph; #define TI(x) x::type_info -static bool eliminate_nop(const std::shared_ptr& node) -{ +static bool eliminate_nop(const std::shared_ptr& node) { // skip if shapes are dynamic if (node->get_input_partial_shape(0).is_dynamic() || - node->get_output_partial_shape(0).is_dynamic()) - { + node->get_output_partial_shape(0).is_dynamic()) { return false; } - if (node->get_input_shape(0) == node->get_output_shape(0)) - { + if (node->get_input_shape(0) == node->get_output_shape(0)) { return replace_output_update_name(node->output(0), node->input_value(0)); } return false; } -static bool eliminate_sum(const std::shared_ptr& node) -{ +static bool eliminate_sum(const std::shared_ptr& node) { auto sum = as_type_ptr(node); - if (sum->get_reduction_axes().empty()) - { + if (sum->get_reduction_axes().empty()) { return replace_output_update_name(node->output(0), node->input_value(0)); } return false; } -static bool eliminate_convert(const std::shared_ptr& node) -{ +static bool eliminate_convert(const std::shared_ptr& node) { bool is_out_type_agnostic = false; static const std::set type_agnostic{TI(opset3::NonZero)}; - if (node->output(0).get_target_inputs().size() == 1) - { + if (node->output(0).get_target_inputs().size() == 1) { Input out = *node->output(0).get_target_inputs().begin(); is_out_type_agnostic = type_agnostic.count(out.get_node()->get_type_info()) == 1; } auto convert = as_type_ptr(node); auto input = convert->input_value(0); - if (convert->get_convert_element_type() == input.get_element_type() || is_out_type_agnostic) - { - if (is_out_type_agnostic && is_type(input.get_node())) - { + if (convert->get_convert_element_type() == input.get_element_type() || is_out_type_agnostic) { + if (is_out_type_agnostic && is_type(input.get_node())) { input = input.get_node()->input_value(0); } return replace_output_update_name(node->output(0), input); @@ -93,36 +69,30 @@ static bool eliminate_convert(const std::shared_ptr& node) return false; } -static bool eliminate_concat(const std::shared_ptr& node) -{ +static bool eliminate_concat(const std::shared_ptr& node) { auto node_input = node->input_value(0); // remove concat with single input - if (node->get_input_size() == 1) - { + if (node->get_input_size() == 1) { return replace_output_update_name(node->output(0), node_input); } return false; } -static bool eliminate_reshape_v1(const std::shared_ptr& node) -{ +static bool eliminate_reshape_v1(const std::shared_ptr& node) { auto input = node->input_value(0); // check if reshape is not identity op - if (input.get_partial_shape().is_dynamic() || node->get_output_partial_shape(0).is_dynamic()) - { + if (input.get_partial_shape().is_dynamic() || node->get_output_partial_shape(0).is_dynamic()) { NGRAPH_DEBUG << node << " has dynamic shapes."; return false; } // remove identity op - if (input.get_shape() == node->get_output_shape(0)) - { + if (input.get_shape() == node->get_output_shape(0)) { return replace_output_update_name(node->output(0), input); } // eliminate redundant reshape, squeeze, or unsqueeze if (is_type(input.get_node()) || - is_type(input.get_node()) || is_type(input.get_node())) - { + is_type(input.get_node()) || is_type(input.get_node())) { auto shape = node->get_output_shape(0); std::vector vi; vi.assign(shape.begin(), shape.end()); @@ -135,43 +105,32 @@ static bool eliminate_reshape_v1(const std::shared_ptr& node) return false; } -static size_t count_unknown_dims(const PartialShape& ps) -{ +static size_t count_unknown_dims(const PartialShape& ps) { size_t rc = 0; - if (ps.is_static()) - { + if (ps.is_static()) { return rc; } - for (auto i = 0; i < ps.rank().get_length(); i++) - { - if (ps[i].is_dynamic()) - { + for (auto i = 0; i < ps.rank().get_length(); i++) { + if (ps[i].is_dynamic()) { rc += 1; } } return rc; } -static bool replace_squeeze_unsqueeze(const std::shared_ptr& node) -{ +static bool replace_squeeze_unsqueeze(const std::shared_ptr& node) { auto shape_ps = node->get_output_partial_shape(0); - if (shape_ps.rank().get_length() == 0) - { + if (shape_ps.rank().get_length() == 0) { return false; } - if (count_unknown_dims(shape_ps) > 1) - { + if (count_unknown_dims(shape_ps) > 1) { return false; } std::vector target_shape; - for (auto i = 0; i < shape_ps.rank().get_length(); i++) - { - if (shape_ps[i].is_dynamic()) - { + for (auto i = 0; i < shape_ps.rank().get_length(); i++) { + if (shape_ps[i].is_dynamic()) { target_shape.emplace_back(-1); - } - else - { + } else { target_shape.emplace_back(shape_ps[i].get_length()); } } @@ -182,41 +141,30 @@ static bool replace_squeeze_unsqueeze(const std::shared_ptr& node) opset3::Constant::create(element::i64, Shape{target_shape.size()}, target_shape); if (is_type(input) || is_type(input) || - is_type(input)) - { + is_type(input)) { reshape = make_shared(input->input_value(0), pat, false); - } - else - { + } else { reshape = make_shared(node->input_value(0), pat, false); } // skip if reshape is nop - if (reshape->get_input_partial_shape(0).same_scheme(shape_ps)) - { + if (reshape->get_input_partial_shape(0).same_scheme(shape_ps)) { return replace_output_update_name(node->output(0), reshape->input_value(0)); - } - else - { + } else { return replace_node_update_name(node, reshape); } - return false; } static std::vector get_unsqueeze_axes(const PartialShape& data_shape, - const PartialShape& out_shape) -{ + const PartialShape& out_shape) { std::vector axes; size_t i = 0; - for (auto o = 0; o < out_shape.rank().get_length(); o++) - { - if (i < data_shape.rank().get_length() && data_shape[i].same_scheme(out_shape[o])) - { + for (auto o = 0; o < out_shape.rank().get_length(); o++) { + if (i < data_shape.rank().get_length() && data_shape[i].same_scheme(out_shape[o])) { i += 1; continue; } - if (out_shape[o].is_static() && out_shape[o] == 1) - { + if (out_shape[o].is_static() && out_shape[o] == 1) { axes.push_back(o); } } @@ -224,31 +172,25 @@ static std::vector get_unsqueeze_axes(const PartialShape& data_shape, } static std::vector get_squeeze_axes(const PartialShape& data_shape, - const PartialShape& out_shape) -{ + const PartialShape& out_shape) { std::vector axes; size_t out_i = 0; - for (auto i = 0; i < data_shape.rank().get_length(); i++) - { - if (out_i < out_shape.rank().get_length() && data_shape[i].same_scheme(out_shape[out_i])) - { + for (auto i = 0; i < data_shape.rank().get_length(); i++) { + if (out_i < out_shape.rank().get_length() && data_shape[i].same_scheme(out_shape[out_i])) { out_i += 1; continue; } - if (data_shape[i].is_static() && data_shape[i] == 1) - { + if (data_shape[i].is_static() && data_shape[i] == 1) { axes.push_back(i); } } return axes; } -static bool eliminate_unsqueeze(const std::shared_ptr& node) -{ +static bool eliminate_unsqueeze(const std::shared_ptr& node) { auto out_shape = node->get_output_partial_shape(0); // try to replace all squeeze/unsqueeze with reshape - if (out_shape.rank().get_length() != 0 && count_unknown_dims(out_shape) < 2) - { + if (out_shape.rank().get_length() != 0 && count_unknown_dims(out_shape) < 2) { return replace_squeeze_unsqueeze(node); } @@ -259,46 +201,37 @@ static bool eliminate_unsqueeze(const std::shared_ptr& node) auto axes_const = opset3::Constant::create(element::i64, Shape{axes.size()}, axes); auto new_unsq = make_shared(input->input_value(0), axes_const); if (unsqueeze->get_output_partial_shape(0).same_scheme( - new_unsq->get_output_partial_shape(0))) - { + new_unsq->get_output_partial_shape(0))) { return replace_node_update_name(unsqueeze, new_unsq); } return false; }; // eliminate redundant squeeze->unsqueeze - if (squeeze) - { + if (squeeze) { const auto& data_shape = squeeze->input_value(0).get_partial_shape(); if (ngraph::compare_constants(squeeze->input_value(1).get_node_shared_ptr(), - unsqueeze->input_value(1).get_node_shared_ptr())) - { + unsqueeze->input_value(1).get_node_shared_ptr())) { return replace_output_update_name(unsqueeze->output(0), squeeze->input_value(0)); } - if (data_shape.rank().is_dynamic() || out_shape.rank().is_dynamic()) - { + if (data_shape.rank().is_dynamic() || out_shape.rank().is_dynamic()) { return false; } - if (out_shape.rank().get_length() > data_shape.rank().get_length()) - { + if (out_shape.rank().get_length() > data_shape.rank().get_length()) { // check if single unsqueeze can handle this auto axes = get_unsqueeze_axes(data_shape, out_shape); - if (axes.size() + data_shape.rank().get_length() == out_shape.rank().get_length()) - { + if (axes.size() + data_shape.rank().get_length() == out_shape.rank().get_length()) { return replace_unsqueeze_only(axes); } } - if (out_shape.rank().get_length() < data_shape.rank().get_length()) - { + if (out_shape.rank().get_length() < data_shape.rank().get_length()) { // check if single squeeze can handle this auto axes = get_squeeze_axes(data_shape, out_shape); - if (data_shape.rank().get_length() - axes.size() == out_shape.rank().get_length()) - { + if (data_shape.rank().get_length() - axes.size() == out_shape.rank().get_length()) { auto axes_const = opset3::Constant::create(element::i64, Shape{axes.size()}, axes); auto new_sq = make_shared(input->input_value(0), axes_const); if (unsqueeze->get_output_partial_shape(0).same_scheme( - new_sq->get_output_partial_shape(0))) - { + new_sq->get_output_partial_shape(0))) { return replace_node_update_name(unsqueeze, new_sq); } return false; @@ -308,11 +241,9 @@ static bool eliminate_unsqueeze(const std::shared_ptr& node) } // eliminate redundant unsqueeze->unsqueeze auto unsqueeze_i = as_type_ptr(input); - if (unsqueeze_i) - { + if (unsqueeze_i) { const auto& data_shape = unsqueeze_i->input_value(0).get_partial_shape(); - if (data_shape.rank().is_dynamic() || out_shape.rank().is_dynamic()) - { + if (data_shape.rank().is_dynamic() || out_shape.rank().is_dynamic()) { return false; } auto axes = get_unsqueeze_axes(data_shape, out_shape); @@ -322,12 +253,10 @@ static bool eliminate_unsqueeze(const std::shared_ptr& node) return false; } -static bool eliminate_squeeze(const std::shared_ptr& node) -{ +static bool eliminate_squeeze(const std::shared_ptr& node) { auto out_shape = node->get_output_partial_shape(0); // try to replace all unsqueeze/squeeze with reshape - if (out_shape.rank().get_length() != 0 && count_unknown_dims(out_shape) < 2) - { + if (out_shape.rank().get_length() != 0 && count_unknown_dims(out_shape) < 2) { return replace_squeeze_unsqueeze(node); } @@ -336,54 +265,42 @@ static bool eliminate_squeeze(const std::shared_ptr& node) auto replace_squeeze_only = [&](const vector& axes) { auto axes_const = opset3::Constant::create(element::i64, Shape{axes.size()}, axes); auto new_sq = make_shared(input->input_value(0), axes_const); - if (squeeze->get_output_partial_shape(0).same_scheme(new_sq->get_output_partial_shape(0))) - { + if (squeeze->get_output_partial_shape(0).same_scheme(new_sq->get_output_partial_shape(0))) { return replace_node_update_name(squeeze, new_sq); } return false; }; // eliminate redundant unsqueeze->squeeze - if (auto unsqueeze = as_type_ptr(input)) - { + if (auto unsqueeze = as_type_ptr(input)) { PartialShape data_shape; - if (op::is_parameter(input)) - { + if (op::is_parameter(input)) { data_shape = unsqueeze->input(0).get_partial_shape(); - } - else - { + } else { data_shape = input->input(0).get_partial_shape(); } if (ngraph::compare_constants(unsqueeze->input_value(1).get_node_shared_ptr(), - squeeze->input_value(1).get_node_shared_ptr())) - { + squeeze->input_value(1).get_node_shared_ptr())) { return replace_output_update_name(squeeze->output(0), unsqueeze->input_value(0)); } - if (data_shape.rank().is_dynamic() || out_shape.rank().is_dynamic()) - { + if (data_shape.rank().is_dynamic() || out_shape.rank().is_dynamic()) { return false; } - if (out_shape.rank().get_length() < data_shape.rank().get_length()) - { + if (out_shape.rank().get_length() < data_shape.rank().get_length()) { // check if single squeeze can handle this auto axes = get_squeeze_axes(data_shape, out_shape); - if (data_shape.rank().get_length() == out_shape.rank().get_length() + axes.size()) - { + if (data_shape.rank().get_length() == out_shape.rank().get_length() + axes.size()) { return replace_squeeze_only(axes); } } - if (out_shape.rank().get_length() > data_shape.rank().get_length()) - { + if (out_shape.rank().get_length() > data_shape.rank().get_length()) { // check if single unsqueeze can handle this auto axes = get_unsqueeze_axes(data_shape, out_shape); - if (data_shape.rank().get_length() + axes.size() == out_shape.rank().get_length()) - { + if (data_shape.rank().get_length() + axes.size() == out_shape.rank().get_length()) { auto axes_const = opset3::Constant::create(element::i64, Shape{axes.size()}, axes); auto new_unsq = make_shared(input->input_value(0), axes_const); if (squeeze->get_output_partial_shape(0).same_scheme( - new_unsq->get_output_partial_shape(0))) - { + new_unsq->get_output_partial_shape(0))) { replace_output_update_name(squeeze, new_unsq); return true; } @@ -392,19 +309,14 @@ static bool eliminate_squeeze(const std::shared_ptr& node) return false; } // eliminate redundant squeeze->squeeze - if (auto squeeze_i = as_type_ptr(input)) - { + if (auto squeeze_i = as_type_ptr(input)) { PartialShape data_shape; - if (op::is_parameter(input)) - { + if (op::is_parameter(input)) { data_shape = squeeze_i->input(0).get_partial_shape(); - } - else - { + } else { data_shape = input->input(0).get_partial_shape(); } - if (data_shape.rank().is_dynamic() || out_shape.rank().is_dynamic()) - { + if (data_shape.rank().is_dynamic() || out_shape.rank().is_dynamic()) { return false; } auto axes = get_squeeze_axes(data_shape, out_shape); @@ -413,14 +325,12 @@ static bool eliminate_squeeze(const std::shared_ptr& node) return false; } -static bool eliminate_stop_gradient(const std::shared_ptr& node) -{ +static bool eliminate_stop_gradient(const std::shared_ptr& node) { replace_output_update_name(node->output(0), node->input_value(0)); return true; } -bool pass::NopElimination::run_on_function(std::shared_ptr function) -{ +bool pass::NopElimination::run_on_function(std::shared_ptr function) { static const std::unordered_map&)>> dispatcher{{TI(op::v0::Pad), &eliminate_nop}, {TI(opset3::Pad), &eliminate_nop}, @@ -436,13 +346,11 @@ bool pass::NopElimination::run_on_function(std::shared_ptr function) bool clobbered = false; - for (const auto& n : function->get_ops()) - { + for (const auto& n : function->get_ops()) { // Work around a warning [-Wpotentially-evaluated-expression] const Node& node = *n; auto handler = dispatcher.find(node.get_type_info()); - if (handler != dispatcher.end()) - { + if (handler != dispatcher.end()) { clobbered = handler->second(n) || clobbered; } } diff --git a/ngraph/test/algebraic_simplification.cpp b/inference-engine/tests/functional/inference_engine/transformations/algebraic_simplification.cpp similarity index 86% rename from ngraph/test/algebraic_simplification.cpp rename to inference-engine/tests/functional/inference_engine/transformations/algebraic_simplification.cpp index 40de990c8c0..e7cad6c06a0 100644 --- a/ngraph/test/algebraic_simplification.cpp +++ b/inference-engine/tests/functional/inference_engine/transformations/algebraic_simplification.cpp @@ -1,61 +1,30 @@ -//***************************************************************************** -// Copyright 2017-2020 Intel Corporation +// Copyright (C) 2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 // -// 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 -#include -#include -#include +#include + +#include "common_test_utils/test_common.hpp" +#include +#include #include +#include -#include "gtest/gtest.h" -#include "ngraph/file_util.hpp" -#include "ngraph/graph_util.hpp" -#include "ngraph/log.hpp" -#include "ngraph/ngraph.hpp" -#include "ngraph/op/add.hpp" -#include "ngraph/op/batch_norm.hpp" -#include "ngraph/op/concat.hpp" -#include "ngraph/op/constant.hpp" -#include "ngraph/op/divide.hpp" -#include "ngraph/op/exp.hpp" -#include "ngraph/op/log.hpp" -#include "ngraph/op/multiply.hpp" -#include "ngraph/op/negative.hpp" -#include "ngraph/op/product.hpp" -#include "ngraph/op/sqrt.hpp" -#include "ngraph/op/subtract.hpp" -#include "ngraph/op/sum.hpp" -#include "ngraph/pass/algebraic_simplification.hpp" -#include "ngraph/pass/constant_folding.hpp" -#include "ngraph/pass/graph_rewrite.hpp" -#include "ngraph/pass/manager.hpp" -#include "ngraph/pass/pass.hpp" -#include "ngraph/pass/visualize_tree.hpp" -#include "ngraph/pattern/matcher.hpp" -#include "ngraph/pattern/op/label.hpp" -#include "ngraph/pattern/op/skip.hpp" -#include "util/all_close.hpp" -#include "util/matcher.hpp" -#include "util/test_tools.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common_test_utils/ngraph_test_utils.hpp" using namespace ngraph; using namespace std; -TEST(algebraic_simplification, add_negative_tests) -{ +TEST(algebraic_simplification, add_negative_tests) { Shape shape{}; auto type = element::f32; pass::Manager pass_manager; @@ -77,14 +46,12 @@ TEST(algebraic_simplification, add_negative_tests) auto expected = ngraph::NodeVector{a, b, add_a_0_0, c, add_b_0_0}; auto results = f->get_results(); - for (size_t i = 0; i < results.size(); i++) - { + for (size_t i = 0; i < results.size(); i++) { ASSERT_EQ(expected.at(i), results.at(i)->input_value(0).get_node_shared_ptr()); } } -TEST(algebraic_simplification, multiply_negative_tests) -{ +TEST(algebraic_simplification, multiply_negative_tests) { Shape shape{}; auto type = element::f32; pass::Manager pass_manager; @@ -106,14 +73,12 @@ TEST(algebraic_simplification, multiply_negative_tests) auto expected = ngraph::NodeVector{a, b, add_a_0_0, c, add_b_0_0}; auto results = f->get_results(); - for (size_t i = 0; i < results.size(); i++) - { + for (size_t i = 0; i < results.size(); i++) { ASSERT_EQ(expected.at(i), results.at(i)->input_value(0).get_node_shared_ptr()); } } -TEST(algebraic_simplification, multiply_prod_negative) -{ +TEST(algebraic_simplification, multiply_prod_negative) { auto fconst1 = ngraph::op::Constant::create(element::f64, Shape{2}, {1.0, 1.0}); auto broadcast = std::make_shared(fconst1, Shape{2, 5}, AxisSet{1}); auto prod_fconst1 = std::make_shared(broadcast, AxisSet{0, 1}); @@ -127,8 +92,7 @@ TEST(algebraic_simplification, multiply_prod_negative) ASSERT_EQ(f_prod, prod_fconst1); } -TEST(algebraic_simplification, multiply_sum_negative) -{ +TEST(algebraic_simplification, multiply_sum_negative) { auto fconst1 = ngraph::op::Constant::create(element::f64, Shape{2}, {1.0, 1.0}); auto broadcast = std::make_shared(fconst1, Shape{2, 5}, AxisSet{1}); auto sum_fconst1 = std::make_shared(broadcast, AxisSet{0, 1}); @@ -142,8 +106,7 @@ TEST(algebraic_simplification, multiply_sum_negative) ASSERT_EQ(f_sum, sum_fconst1); } -TEST(algebraic_simplification, concat_parameter_slices_reversed) -{ +TEST(algebraic_simplification, concat_parameter_slices_reversed) { auto a = make_shared(element::f32, Shape{96, 100}); auto slice1 = make_shared(a, Coordinate{0, 0}, Coordinate{32, 100}, Strides{1, 1}); auto slice2 = make_shared(a, Coordinate{32, 0}, Coordinate{64, 100}, Strides{1, 1}); @@ -160,8 +123,7 @@ TEST(algebraic_simplification, concat_parameter_slices_reversed) ASSERT_EQ(f->get_results().at(0)->input_value(0).get_node_shared_ptr(), concat); } -TEST(algebraic_simplification, concat_parameter_slices_element_count) -{ +TEST(algebraic_simplification, concat_parameter_slices_element_count) { auto a = make_shared(element::f32, Shape{96, 100}); // slicing 30 elements out of 96; should trigger a check that some elements are missing auto slice1 = make_shared(a, Coordinate{0, 0}, Coordinate{10, 100}, Strides{1, 1}); @@ -179,8 +141,7 @@ TEST(algebraic_simplification, concat_parameter_slices_element_count) ASSERT_EQ(f->get_results().at(0)->input_value(0).get_node_shared_ptr(), concat); } -TEST(algebraic_simplification, concat_parameter_non_uniform_slices) -{ +TEST(algebraic_simplification, concat_parameter_non_uniform_slices) { auto a = make_shared(element::f32, Shape{96, 100}); auto slice1 = make_shared(a, Coordinate{0, 0}, Coordinate{38, 100}, Strides{1, 1}); auto slice2 = make_shared(a, Coordinate{38, 0}, Coordinate{64, 100}, Strides{1, 1}); @@ -197,8 +158,7 @@ TEST(algebraic_simplification, concat_parameter_non_uniform_slices) ASSERT_EQ(f->get_results().at(0)->input_value(0).get_node_shared_ptr(), concat); } -TEST(algebraic_simplification, concat_different_inputs) -{ +TEST(algebraic_simplification, concat_different_inputs) { auto a = make_shared(element::f32, Shape{96, 100}); auto goe1 = -a; auto goe2 = -a; @@ -220,8 +180,7 @@ TEST(algebraic_simplification, concat_different_inputs) ASSERT_EQ(f->get_results().at(0)->input_value(0).get_node_shared_ptr(), concat); } -TEST(algebraic_simplification, log_no_exp) -{ +TEST(algebraic_simplification, log_no_exp) { auto a = make_shared(element::f32, Shape{96, 100}); auto b = make_shared(element::f32, Shape{96, 100}); auto abs_a = make_shared(a); @@ -241,8 +200,7 @@ TEST(algebraic_simplification, log_no_exp) ASSERT_EQ(neg_inner->input_value(0).get_node_shared_ptr(), log_div); } -TEST(algebraic_simplification, log_no_divide) -{ +TEST(algebraic_simplification, log_no_divide) { auto a = make_shared(element::f32, Shape{96, 100}); auto b = make_shared(element::f32, Shape{96, 100}); auto exp_a = make_shared(a); @@ -262,15 +220,13 @@ TEST(algebraic_simplification, log_no_divide) ASSERT_EQ(neg_inner->input_value(0).get_node_shared_ptr(), log_mul); } -TEST(algebraic_simplification, pass_property) -{ +TEST(algebraic_simplification, pass_property) { auto pass = std::make_shared(); ASSERT_FALSE(pass->get_property(pass::PassProperty::CHANGE_DYNAMIC_STATE)); } -TEST(algebraic_simplification, replace_transpose_with_reshape) -{ +TEST(algebraic_simplification, replace_transpose_with_reshape) { auto check_usecase = [](const PartialShape& shape, const std::vector& perm_val, bool i32, @@ -280,25 +236,19 @@ TEST(algebraic_simplification, replace_transpose_with_reshape) auto casename = string("usecase #") + to_string(++id); shared_ptr perm; - if (i32) - { + if (i32) { std::vector perm_val_i32(perm_val.begin(), perm_val.end()); perm = op::Constant::create(element::i32, Shape{perm_val.size()}, perm_val_i32); - } - else - { + } else { perm = op::Constant::create(element::i64, Shape{perm_val.size()}, perm_val); } auto param = make_shared(element::f32, shape); shared_ptr A1; - if (multiout) - { + if (multiout) { auto last_dim = shape.rank().get_length() - 1; A1 = make_shared(param, last_dim, element::i32); - } - else - { + } else { A1 = make_shared(param); } auto transpose = make_shared((multiout ? A1->output(0) : A1), perm); @@ -324,8 +274,7 @@ TEST(algebraic_simplification, replace_transpose_with_reshape) }; for (auto& i32 : {true, false}) - for (auto& multiout : {true, false}) - { + for (auto& multiout : {true, false}) { check_usecase(Shape{1, 3}, vector{1, 0}, i32, multiout, 0); check_usecase(Shape{2, 3, 1}, vector{2, 0, 1}, i32, multiout, 0); check_usecase(Shape{10, 20, 1, 1}, vector{0, 2, 3, 1}, i32, multiout, 0); @@ -363,8 +312,7 @@ TEST(algebraic_simplification, replace_transpose_with_reshape) // gather is Nop and will be removed during `simplify_gather` // algebraic_simplification pass -TEST(algebraic_simplification, gather_3d_indices_constant_axis_1) -{ +TEST(algebraic_simplification, gather_3d_indices_constant_axis_1) { auto check_usecase = [](const PartialShape& pshape, bool i32, bool multiout, @@ -376,15 +324,12 @@ TEST(algebraic_simplification, gather_3d_indices_constant_axis_1) shared_ptr indices; shared_ptr axis; - if (i32) - { + if (i32) { std::vector indices_val_i32(indices_val.begin(), indices_val.end()); indices = op::Constant::create( element::i32, Shape{indices_val.size()}, indices_val_i32); axis = op::Constant::create(element::i32, Shape{}, {(int32_t)axis_val}); - } - else - { + } else { indices = op::Constant::create(element::i64, Shape{indices_val.size()}, indices_val); axis = op::Constant::create(element::i64, Shape{}, {axis_val}); @@ -392,13 +337,10 @@ TEST(algebraic_simplification, gather_3d_indices_constant_axis_1) auto A = make_shared(element::f32, pshape); shared_ptr A1; - if (multiout) - { + if (multiout) { auto last_dim = pshape.rank().get_length() - 1; A1 = make_shared(A, last_dim, element::i32); - } - else - { + } else { A1 = make_shared(A); } auto G = make_shared((multiout ? A1->output(0) : A1), indices, axis); @@ -422,8 +364,7 @@ TEST(algebraic_simplification, gather_3d_indices_constant_axis_1) ASSERT_EQ(count_ops_of_type(optimized_f), num) << casename; }; for (auto& i32 : {true, false}) - for (auto& multiout : {true, false}) - { + for (auto& multiout : {true, false}) { check_usecase(PartialShape{1, 3, 2}, i32, multiout, std::vector{1}, 0, 0); check_usecase(PartialShape{3, 2, 1}, i32, multiout, std::vector{0, 1}, 1, 0); check_usecase(PartialShape{3, 2, 1}, i32, multiout, std::vector{1}, 2, 0); @@ -431,8 +372,7 @@ TEST(algebraic_simplification, gather_3d_indices_constant_axis_1) } } -TEST(algebraic_simplification, gather_shapeof) -{ +TEST(algebraic_simplification, gather_shapeof) { auto check_usecase = [](const PartialShape& pshape, bool is_scalar_index, bool opset2, @@ -446,17 +386,14 @@ TEST(algebraic_simplification, gather_shapeof) shared_ptr indices; shared_ptr axis; - if (i32) - { + if (i32) { std::vector indices_val_i32(indices_val.begin(), indices_val.end()); indices = is_scalar_index ? op::Constant::create(element::i32, Shape{}, indices_val_i32) : op::Constant::create( element::i32, Shape{indices_val.size()}, indices_val_i32); axis = op::Constant::create(element::i32, Shape{}, {(int32_t)axis_val}); - } - else - { + } else { indices = is_scalar_index ? op::Constant::create(element::i64, Shape{}, indices_val) : op::Constant::create( @@ -471,23 +408,17 @@ TEST(algebraic_simplification, gather_shapeof) auto A = make_shared(element::f32, pshape); auto AA = make_shared(element::f64, pshape_1); shared_ptr A1; - if (multiout) - { + if (multiout) { A1 = make_shared(A, AA); - } - else - { + } else { A1 = make_shared(A); } auto B = make_shared( (multiout ? (multiout_1 ? A1->output(1) : A1->output(0)) : A1), indices, axis); shared_ptr B1; - if (opset2) - { + if (opset2) { B1 = make_shared(B); - } - else - { + } else { B1 = make_shared(B); } auto baseline_f = make_shared( @@ -510,16 +441,13 @@ TEST(algebraic_simplification, gather_shapeof) ASSERT_EQ(count_ops_of_type(baseline_f), 1) << casename; auto last_node = optimized_f->get_results()[0]->input_value(0).get_node_shared_ptr(); - if (is_scalar_index) - { + if (is_scalar_index) { ASSERT_EQ(count_ops_of_type(optimized_f), 1) << casename; ASSERT_EQ(count_ops_of_type(optimized_f), 1) << casename; EXPECT_TRUE( as_type_ptr(last_node->input_value(0).get_node_shared_ptr())) << casename; - } - else - { + } else { ASSERT_EQ(count_ops_of_type(optimized_f), 1) << casename; EXPECT_TRUE( as_type_ptr(last_node->input_value(0).get_node_shared_ptr())) @@ -530,8 +458,7 @@ TEST(algebraic_simplification, gather_shapeof) for (auto& opset2 : {true, false}) for (auto& i32 : {true, false}) for (auto& multiout : {true, false}) - for (auto& multiout_1 : {true, false}) - { + for (auto& multiout_1 : {true, false}) { check_usecase(PartialShape{2, 3, 2, 1}, true, opset2, @@ -552,8 +479,7 @@ TEST(algebraic_simplification, gather_shapeof) for (auto& opset2 : {true, false}) for (auto& i32 : {true, false}) for (auto& multiout : {true, false}) - for (auto& multiout_1 : {true, false}) - { + for (auto& multiout_1 : {true, false}) { check_usecase(PartialShape{2, 3, 2, 1}, false, opset2, diff --git a/ngraph/test/nop_elimination.cpp b/inference-engine/tests/functional/inference_engine/transformations/nop_elimination.cpp similarity index 90% rename from ngraph/test/nop_elimination.cpp rename to inference-engine/tests/functional/inference_engine/transformations/nop_elimination.cpp index 16270ab9dc9..77dea90d9bc 100644 --- a/ngraph/test/nop_elimination.cpp +++ b/inference-engine/tests/functional/inference_engine/transformations/nop_elimination.cpp @@ -1,34 +1,29 @@ -//***************************************************************************** -// Copyright 2017-2020 Intel Corporation +// Copyright (C) 2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 // -// 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 + +#include "common_test_utils/test_common.hpp" +#include +#include #include +#include -#include "gtest/gtest.h" -#include "ngraph/ngraph.hpp" -#include "ngraph/opsets/opset1.hpp" -#include "ngraph/pass/manager.hpp" -#include "ngraph/pass/nop_elimination.hpp" -#include "util/all_close.hpp" -#include "util/test_tools.hpp" +#include +#include +#include +#include +#include +#include +#include + +#include "common_test_utils/ngraph_test_utils.hpp" using namespace ngraph; using namespace std; -TEST(nop_elimination, eliminate_pad) -{ +TEST(nop_elimination, eliminate_pad) { Shape shape_a{2}; auto A = make_shared(element::f32, shape_a); Shape shape_b{}; @@ -45,8 +40,7 @@ TEST(nop_elimination, eliminate_pad) ASSERT_EQ(count_ops_of_type(f), 0); } -TEST(nop_elimination, eliminate_sum) -{ +TEST(nop_elimination, eliminate_sum) { Shape shape{2, 2}; auto A = make_shared(element::f32, shape); auto s = make_shared(A, AxisSet{}); @@ -59,8 +53,7 @@ TEST(nop_elimination, eliminate_sum) ASSERT_EQ(count_ops_of_type(f), 0); } -TEST(nop_elimination, eliminate_convert) -{ +TEST(nop_elimination, eliminate_convert) { Shape shape{}; auto type = element::f32; auto A = make_shared(type, shape); @@ -74,8 +67,7 @@ TEST(nop_elimination, eliminate_convert) ASSERT_EQ(count_ops_of_type(f), 0); } -TEST(nop_elimination, convert_type_agnostic) -{ +TEST(nop_elimination, convert_type_agnostic) { Shape shape{}; auto type = element::from(); auto A = make_shared(type, shape); @@ -92,8 +84,7 @@ TEST(nop_elimination, convert_type_agnostic) ASSERT_EQ(count_ops_of_type(f), 0); } -TEST(nop_elimination, eliminate_slice) -{ +TEST(nop_elimination, eliminate_slice) { Shape shape{2, 2}; auto A = make_shared(element::f32, shape); auto s = make_shared(A, Coordinate{0, 0}, Coordinate{2, 2}); @@ -106,8 +97,7 @@ TEST(nop_elimination, eliminate_slice) ASSERT_EQ(count_ops_of_type(f), 0); } -TEST(nop_elimination, eliminate_broadcast) -{ +TEST(nop_elimination, eliminate_broadcast) { Shape shape{}; auto A = make_shared(element::f32, shape); auto b = make_shared(A, shape, AxisSet{}); @@ -120,8 +110,7 @@ TEST(nop_elimination, eliminate_broadcast) ASSERT_EQ(count_ops_of_type(f), 0); } -TEST(nop_elimination, eliminate_stop_gradient) -{ +TEST(nop_elimination, eliminate_stop_gradient) { Shape shape{}; auto A = make_shared(element::f32, shape); auto s = make_shared(A); @@ -134,14 +123,12 @@ TEST(nop_elimination, eliminate_stop_gradient) ASSERT_EQ(count_ops_of_type(f), 0); } -TEST(nop_elimination, pass_property) -{ +TEST(nop_elimination, pass_property) { auto pass = std::make_shared(); ASSERT_FALSE(pass->get_property(pass::PassProperty::CHANGE_DYNAMIC_STATE)); } -TEST(nop_elimination, reshape_elimination_v1) -{ +TEST(nop_elimination, reshape_elimination_v1) { auto generate_func = [](bool zero) { auto arg = std::make_shared(element::i64, PartialShape{8, 16, 2, 3}); auto pattern_org = op::Constant::create(element::i64, Shape{3}, vector{8, 16, 6}); @@ -167,8 +154,7 @@ TEST(nop_elimination, reshape_elimination_v1) ASSERT_TRUE(count_ops_of_type(func_zero) == 1); } -TEST(nop_elimination, reshape_elimination_v1_dynamic) -{ +TEST(nop_elimination, reshape_elimination_v1_dynamic) { auto arg = std::make_shared(element::i64, PartialShape::dynamic()); auto pattern = make_shared(element::i64, PartialShape::dynamic(1)); auto reshape_v1 = std::make_shared(arg, pattern, false); @@ -180,8 +166,7 @@ TEST(nop_elimination, reshape_elimination_v1_dynamic) ASSERT_TRUE(count_ops_of_type(f) == 1); } -TEST(nop_elimination, concat_elimination_single_node) -{ +TEST(nop_elimination, concat_elimination_single_node) { int64_t a = 0; auto A = make_shared(element::f32, Shape{2, 3}); auto f = @@ -195,8 +180,7 @@ TEST(nop_elimination, concat_elimination_single_node) ASSERT_EQ(count_ops_of_type(f), 1); } -TEST(nop_elimination, concat_elimination_single_input) -{ +TEST(nop_elimination, concat_elimination_single_input) { int64_t a = 0; auto A = make_shared(element::f32, Shape{2, 3}); auto B = make_shared(NodeVector{A}, a); @@ -210,8 +194,7 @@ TEST(nop_elimination, concat_elimination_single_input) ASSERT_EQ(count_ops_of_type(f), 0); } -TEST(nop_elimination, concat_elimination_single_input_dynamic) -{ +TEST(nop_elimination, concat_elimination_single_input_dynamic) { int64_t a = 0; auto A = make_shared(element::f32, PartialShape{Dimension::dynamic(), 3}); auto B = make_shared(NodeVector{A}, a); @@ -225,8 +208,7 @@ TEST(nop_elimination, concat_elimination_single_input_dynamic) ASSERT_EQ(count_ops_of_type(f), 0); } -TEST(nop_elimination, unsqueeze_elimination) -{ +TEST(nop_elimination, unsqueeze_elimination) { const auto axis = op::Constant::create(element::i64, {}, {0}); const auto A = make_shared( element::f32, PartialShape{3, Dimension::dynamic(), Dimension::dynamic()}); @@ -241,8 +223,7 @@ TEST(nop_elimination, unsqueeze_elimination) ASSERT_EQ(count_ops_of_type(f), 1); } -TEST(nop_elimination, squeeze_unsqueeze_overlap_elimination) -{ +TEST(nop_elimination, squeeze_unsqueeze_overlap_elimination) { auto check_usecase = [](const PartialShape& shape, const std::vector& sq_axes_val, const std::vector& unsq_axes_val, @@ -257,17 +238,14 @@ TEST(nop_elimination, squeeze_unsqueeze_overlap_elimination) shared_ptr sq_axes; shared_ptr unsq_axes; - if (i32) - { + if (i32) { std::vector sq_axes_val_i32(sq_axes_val.begin(), sq_axes_val.end()); std::vector unsq_axes_val_i32(unsq_axes_val.begin(), unsq_axes_val.end()); sq_axes = op::Constant::create( element::i32, Shape{sq_axes_val.size()}, sq_axes_val_i32); unsq_axes = op::Constant::create( element::i32, Shape{unsq_axes_val.size()}, unsq_axes_val_i32); - } - else - { + } else { sq_axes = op::Constant::create(element::i64, Shape{sq_axes_val.size()}, sq_axes_val); unsq_axes = op::Constant::create( @@ -276,24 +254,18 @@ TEST(nop_elimination, squeeze_unsqueeze_overlap_elimination) auto A = make_shared(element::f32, shape); shared_ptr A1; - if (multiout) - { + if (multiout) { auto last_dim = shape.rank().get_length() - 1; A1 = make_shared(A, last_dim, element::i32); - } - else - { + } else { A1 = make_shared(A); } shared_ptr B1; - if (sq_to_unsq) - { + if (sq_to_unsq) { auto B = make_shared((multiout ? A1->output(0) : A1), sq_axes); B1 = make_shared(B, unsq_axes); - } - else - { + } else { auto B = make_shared((multiout ? A1->output(0) : A1), unsq_axes); B1 = make_shared(B, sq_axes); } @@ -496,8 +468,7 @@ TEST(nop_elimination, squeeze_unsqueeze_overlap_elimination) 0); } -TEST(nop_elimination, squeeze_squeeze_overlap_elimination) -{ +TEST(nop_elimination, squeeze_squeeze_overlap_elimination) { auto check_usecase = [](const PartialShape& shape, const std::vector& sq_axes_val_1, const std::vector& sq_axes_val_2, @@ -525,7 +496,6 @@ TEST(nop_elimination, squeeze_squeeze_overlap_elimination) ASSERT_EQ(ps.rank().get_length(), ps_r.rank().get_length()) << casename; ASSERT_EQ(count_ops_of_type(baseline_f), 2) << casename; ASSERT_EQ(count_ops_of_type(optimized_f), sq) << casename; - ; }; check_usecase(PartialShape{1, Dimension::dynamic(), 1, Dimension::dynamic()}, {0}, {1}, 1); @@ -537,8 +507,7 @@ TEST(nop_elimination, squeeze_squeeze_overlap_elimination) PartialShape{1, Dimension::dynamic(), 1, Dimension::dynamic(), 1}, {0}, {1, 3}, 1); } -TEST(nop_elimination, unsqueeze_unsqueeze_overlap_elimination) -{ +TEST(nop_elimination, unsqueeze_unsqueeze_overlap_elimination) { auto check_usecase = [](const PartialShape& shape, const std::vector& unsq_axes_val_1, const std::vector& unsq_axes_val_2, @@ -566,7 +535,6 @@ TEST(nop_elimination, unsqueeze_unsqueeze_overlap_elimination) ASSERT_EQ(ps.rank().get_length(), ps_r.rank().get_length()) << casename; ASSERT_EQ(count_ops_of_type(baseline_f), 2) << casename; ASSERT_EQ(count_ops_of_type(optimized_f), unsq) << casename; - ; }; check_usecase(PartialShape{Dimension::dynamic(), 1, Dimension::dynamic()}, {0}, {2}, 1); @@ -576,8 +544,7 @@ TEST(nop_elimination, unsqueeze_unsqueeze_overlap_elimination) check_usecase(PartialShape{Dimension::dynamic(), 1, Dimension::dynamic(), 1}, {0}, {1, 3}, 1); } -TEST(nop_elimination, unsqueeze_squeeze_elimination) -{ +TEST(nop_elimination, unsqueeze_squeeze_elimination) { auto generate_func = [](const Shape& shape, const std::vector& axes_val) { auto axes = op::Constant::create(element::i64, Shape{axes_val.size()}, axes_val); auto A = make_shared(element::f32, shape); @@ -590,7 +557,7 @@ TEST(nop_elimination, unsqueeze_squeeze_elimination) auto check_usecase = [&](const Shape& shape, const std::vector& axes_val) { auto baseline_f = generate_func(shape, axes_val); auto optimized_f = generate_func(shape, axes_val); - EXPECT_TRUE((compare_pass_int(baseline_f, optimized_f))); + pass::NopElimination().run_on_function(optimized_f); ASSERT_EQ(count_ops_of_type(baseline_f), 1); ASSERT_EQ(count_ops_of_type(baseline_f), 1); @@ -604,8 +571,7 @@ TEST(nop_elimination, unsqueeze_squeeze_elimination) check_usecase(Shape{3, 2}, std::vector{-1, -4}); } -TEST(nop_elimination, reshape_unsqueeze_elimination) -{ +TEST(nop_elimination, reshape_unsqueeze_elimination) { auto check_usecase = [](const Shape& shape, const std::vector& pat_val, bool zero, @@ -621,7 +587,7 @@ TEST(nop_elimination, reshape_unsqueeze_elimination) auto B1 = make_shared(B, axes); auto baseline_f = make_shared(make_shared(B1), ParameterVector{A}); auto optimized_f = clone_function(*baseline_f); - EXPECT_TRUE((compare_pass_int(baseline_f, optimized_f))); + pass::NopElimination().run_on_function(optimized_f); ASSERT_EQ(count_ops_of_type(baseline_f), 1); ASSERT_EQ(count_ops_of_type(baseline_f), 1); @@ -634,8 +600,7 @@ TEST(nop_elimination, reshape_unsqueeze_elimination) check_usecase(Shape{2, 3, 2}, {2, -1, 2}, false, {2}); check_usecase(Shape{2, 3, 2, 1}, {2, 3, 2}, false, {0}); } -TEST(nop_elimination, reshape_squeeze_elimination) -{ +TEST(nop_elimination, reshape_squeeze_elimination) { auto check_usecase = [](const Shape& shape, const std::vector& pat_val, bool zero, @@ -651,7 +616,7 @@ TEST(nop_elimination, reshape_squeeze_elimination) auto B1 = make_shared(B, axes); auto baseline_f = make_shared(make_shared(B1), ParameterVector{A}); auto optimized_f = clone_function(*baseline_f); - EXPECT_TRUE((compare_pass_int(baseline_f, optimized_f))); + pass::NopElimination().run_on_function(optimized_f); ASSERT_EQ(count_ops_of_type(baseline_f), 1); ASSERT_EQ(count_ops_of_type(baseline_f), 1); @@ -665,8 +630,7 @@ TEST(nop_elimination, reshape_squeeze_elimination) check_usecase(Shape{2, 3, 2, 1}, {1, 2, 3, 2}, false, {0}); } -TEST(nop_elimination, reshape_reshape_elimination) -{ +TEST(nop_elimination, reshape_reshape_elimination) { auto check_usecase = [](const Shape& shape, const std::vector& pat_val, bool zero) { auto pat = op::Constant::create(element::i64, Shape{pat_val.size()}, pat_val); auto A = make_shared(element::f32, shape); @@ -678,7 +642,7 @@ TEST(nop_elimination, reshape_reshape_elimination) auto B1 = make_shared(B, pat2, true); auto baseline_f = make_shared(make_shared(B1), ParameterVector{A}); auto optimized_f = clone_function(*baseline_f); - EXPECT_TRUE((compare_pass_int(baseline_f, optimized_f))); + pass::NopElimination().run_on_function(optimized_f); ASSERT_EQ(count_ops_of_type(baseline_f), 2); ASSERT_EQ(count_ops_of_type(optimized_f), 1); @@ -691,8 +655,7 @@ TEST(nop_elimination, reshape_reshape_elimination) check_usecase(Shape{2, 3, 2, 1}, ::vector{2, 3, 2}, false); } -TEST(nop_elimination, squeeze_reshape_elimination) -{ +TEST(nop_elimination, squeeze_reshape_elimination) { auto check_usecase = [](const Shape& shape, const std::vector& indices_val) { auto indices = op::Constant::create(element::i64, Shape{indices_val.size()}, indices_val); @@ -704,7 +667,7 @@ TEST(nop_elimination, squeeze_reshape_elimination) auto B1 = make_shared(B, pat2, false); auto baseline_f = make_shared(make_shared(B1), ParameterVector{A}); auto optimized_f = clone_function(*baseline_f); - EXPECT_TRUE((compare_pass_int(baseline_f, optimized_f))); + pass::NopElimination().run_on_function(optimized_f); ASSERT_EQ(count_ops_of_type(baseline_f), 1); ASSERT_EQ(count_ops_of_type(baseline_f), 1); @@ -718,8 +681,7 @@ TEST(nop_elimination, squeeze_reshape_elimination) check_usecase(Shape{1, 6, 2, 1}, std::vector{3}); } -TEST(nop_elimination, unsqueeze_reshape_elimination) -{ +TEST(nop_elimination, unsqueeze_reshape_elimination) { auto check_usecase = [](const Shape& shape, const std::vector& indices_val) { auto indices = op::Constant::create(element::i64, Shape{indices_val.size()}, indices_val); @@ -731,7 +693,7 @@ TEST(nop_elimination, unsqueeze_reshape_elimination) auto B1 = make_shared(B, pat2, false); auto baseline_f = make_shared(make_shared(B1), ParameterVector{A}); auto optimized_f = clone_function(*baseline_f); - EXPECT_TRUE((compare_pass_int(baseline_f, optimized_f))); + pass::NopElimination().run_on_function(optimized_f); ASSERT_EQ(count_ops_of_type(baseline_f), 1); ASSERT_EQ(count_ops_of_type(baseline_f), 1); @@ -745,15 +707,14 @@ TEST(nop_elimination, unsqueeze_reshape_elimination) check_usecase(Shape{1, 6, 2}, std::vector{3}); } -TEST(nop_elimination, squeeze_unsqueeze_elimination_negative) -{ +TEST(nop_elimination, squeeze_unsqueeze_elimination_negative) { auto check_usecase = [](const Shape& shape, const std::vector& indices_val) { auto indices = op::Constant::create(element::i64, Shape{indices_val.size()}, indices_val); auto input = make_shared(element::f32, shape); auto squeeze = make_shared(input, indices); auto baseline_f = make_shared(squeeze, ParameterVector{input}); auto optimized_f = clone_function(*baseline_f); - EXPECT_TRUE((compare_pass_int(baseline_f, optimized_f))); + pass::NopElimination().run_on_function(optimized_f); ASSERT_EQ(count_ops_of_type(baseline_f), 1); ASSERT_EQ(count_ops_of_type(optimized_f), 1); @@ -762,8 +723,7 @@ TEST(nop_elimination, squeeze_unsqueeze_elimination_negative) check_usecase(Shape{1, 1, 1}, std::vector{0, 1, 2}); } -TEST(nop_elimination, topk_convert_elimination) -{ +TEST(nop_elimination, topk_convert_elimination) { auto check_usecase = []() { auto A = make_shared(element::f32, Shape{20, 3, 4}); auto A1 = make_shared(A); @@ -771,8 +731,7 @@ TEST(nop_elimination, topk_convert_elimination) auto C = make_shared(B->output(0), B->output(0).get_element_type()); auto baseline_f = make_shared(make_shared(C), ParameterVector{A}); auto optimized_f = clone_function(*baseline_f); - EXPECT_TRUE( - (compare_pass_int(baseline_f, optimized_f))); + pass::NopElimination().run_on_function(optimized_f); ASSERT_EQ(count_ops_of_type(baseline_f), 1); ASSERT_EQ(count_ops_of_type(optimized_f), 0); diff --git a/inference-engine/tests/functional/inference_engine/transformations/transpose_to_reshape_test.cpp b/inference-engine/tests/functional/inference_engine/transformations/transpose_to_reshape_test.cpp index a512affde1b..3ab8ce3ba62 100644 --- a/inference-engine/tests/functional/inference_engine/transformations/transpose_to_reshape_test.cpp +++ b/inference-engine/tests/functional/inference_engine/transformations/transpose_to_reshape_test.cpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include "common_test_utils/ngraph_test_utils.hpp" diff --git a/inference-engine/tests/ie_test_utils/common_test_utils/ngraph_test_utils.cpp b/inference-engine/tests/ie_test_utils/common_test_utils/ngraph_test_utils.cpp index 94ca931be6a..3cac75bbc50 100644 --- a/inference-engine/tests/ie_test_utils/common_test_utils/ngraph_test_utils.cpp +++ b/inference-engine/tests/ie_test_utils/common_test_utils/ngraph_test_utils.cpp @@ -10,6 +10,7 @@ #include #include #include +#include "ngraph_test_utils.hpp" std::pair compare_functions(const std::shared_ptr & f1, const std::shared_ptr & f2) { /* @@ -91,3 +92,5 @@ void check_rt_info(const std::shared_ptr & f) { throw ngraph::ngraph_error(err_msg); } } + +NGRAPH_RTTI_DEFINITION(TestOpMultiOut, "TestOp", 0); diff --git a/inference-engine/tests/ie_test_utils/common_test_utils/ngraph_test_utils.hpp b/inference-engine/tests/ie_test_utils/common_test_utils/ngraph_test_utils.hpp index 9a280ee89ec..c8d14964924 100644 --- a/inference-engine/tests/ie_test_utils/common_test_utils/ngraph_test_utils.hpp +++ b/inference-engine/tests/ie_test_utils/common_test_utils/ngraph_test_utils.hpp @@ -43,3 +43,36 @@ public: private: injection_callback m_callback; }; + +template +size_t count_ops_of_type(std::shared_ptr f) { + size_t count = 0; + for (auto op : f->get_ops()) { + if (ngraph::is_type(op)) { + count++; + } + } + + return count; +} + +class TestOpMultiOut : public ngraph::op::Op { +public: + NGRAPH_RTTI_DECLARATION; + TestOpMultiOut() = default; + + TestOpMultiOut(const ngraph::Output& output_1, const ngraph::Output& output_2) + : Op({output_1, output_2}) { + validate_and_infer_types(); + } + void validate_and_infer_types() override { + set_output_size(2); + set_output_type(0, get_input_element_type(0), get_input_partial_shape(0)); + set_output_type(1, get_input_element_type(1), get_input_partial_shape(1)); + } + + std::shared_ptr + clone_with_new_inputs(const ngraph::OutputVector& new_args) const override { + return std::make_shared(new_args.at(0), new_args.at(1)); + } +}; diff --git a/ngraph/core/include/ngraph/pass/nop_elimination.hpp b/ngraph/core/include/ngraph/pass/nop_elimination.hpp deleted file mode 100644 index 07551f14df3..00000000000 --- a/ngraph/core/include/ngraph/pass/nop_elimination.hpp +++ /dev/null @@ -1,31 +0,0 @@ -//***************************************************************************** -// Copyright 2017-2020 Intel Corporation -// -// 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. -//***************************************************************************** - -#pragma once - -#include "ngraph/pass/pass.hpp" - -namespace ngraph -{ - namespace pass - { - class NGRAPH_API NopElimination : public FunctionPass - { - public: - bool run_on_function(std::shared_ptr function) override; - }; - } -} diff --git a/ngraph/test/CMakeLists.txt b/ngraph/test/CMakeLists.txt index dc3e444053e..cd5a2d044f7 100644 --- a/ngraph/test/CMakeLists.txt +++ b/ngraph/test/CMakeLists.txt @@ -68,7 +68,6 @@ set(SRC misc.cpp ngraph_api.cpp node_input_output.cpp - nop_elimination.cpp op.cpp op_eval/hswish.cpp op_eval/matmul.cpp