forked from openvinotoolkit/openvino
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add transformation to convert adaptive pool to reduce (openvinotoolki…
…t#17488) * Add transformation to convert adaptive pool to reduce * Update src/common/transformations/src/transformations/common_optimizations/moc_transformations.cpp * Add tests and apply feedback * Simplify if branches * Add to common pipeline * Remove 3d AdaptivePool with out_shape 1 * Skip test instead of remove --------- Co-authored-by: Andrei Kochin <[email protected]>
- Loading branch information
1 parent
0b48fc7
commit 41de4ba
Showing
5 changed files
with
195 additions
and
1 deletion.
There are no files selected for viewing
29 changes: 29 additions & 0 deletions
29
.../transformations/include/transformations/common_optimizations/adaptive_pool_to_reduce.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Copyright (C) 2018-2023 Intel Corporation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
#pragma once | ||
|
||
#include <memory> | ||
#include <openvino/pass/graph_rewrite.hpp> | ||
#include <transformations_visibility.hpp> | ||
#include <vector> | ||
|
||
namespace ov { | ||
namespace pass { | ||
|
||
class TRANSFORMATIONS_API AdaptivePoolToReduce; | ||
|
||
} // namespace pass | ||
} // namespace ov | ||
|
||
/** | ||
* @ingroup ie_transformation_common_api | ||
* @brief AdaptivePoolToReduce transformation replaces AdaptiveXXXPool with ReduceXXX when possible | ||
*/ | ||
|
||
class ov::pass::AdaptivePoolToReduce : public ov::pass::MatcherPass { | ||
public: | ||
OPENVINO_RTTI("AdaptivePoolToReduce", "0"); | ||
AdaptivePoolToReduce(); | ||
}; |
63 changes: 63 additions & 0 deletions
63
...mmon/transformations/src/transformations/common_optimizations/adaptive_pool_to_reduce.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Copyright (C) 2018-2023 Intel Corporation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
#include "transformations/common_optimizations/adaptive_pool_to_reduce.hpp" | ||
|
||
#include <memory> | ||
#include <vector> | ||
|
||
#include "itt.hpp" | ||
#include "openvino/core/rt_info.hpp" | ||
#include "openvino/op/adaptive_avg_pool.hpp" | ||
#include "openvino/op/adaptive_max_pool.hpp" | ||
#include "openvino/op/constant.hpp" | ||
#include "openvino/op/reduce_max.hpp" | ||
#include "openvino/op/reduce_mean.hpp" | ||
#include "openvino/pass/pattern/op/wrap_type.hpp" | ||
#include "transformations/utils/utils.hpp" | ||
|
||
using namespace ov::op; | ||
|
||
ov::pass::AdaptivePoolToReduce::AdaptivePoolToReduce() { | ||
MATCHER_SCOPE(AdaptivePoolToReduce); | ||
auto data_pattern = pattern::any_input(); | ||
auto out_spatial_shape = pattern::wrap_type<v0::Constant>(); | ||
auto a_pool = pattern::wrap_type<v8::AdaptiveAvgPool, v8::AdaptiveMaxPool>({data_pattern, out_spatial_shape}); | ||
|
||
ov::matcher_pass_callback callback = [=](pattern::Matcher& m) { | ||
const auto& pattern_map = m.get_pattern_map(); | ||
|
||
const auto& spatial_shape_c = std::dynamic_pointer_cast<v0::Constant>(pattern_map.at(out_spatial_shape)); | ||
auto spatial_shape = spatial_shape_c->cast_vector<int64_t>(); | ||
// Verify that all dimensions in adaptive pool shape are 1 | ||
for (auto& s : spatial_shape) { | ||
if (s != 1) | ||
return false; | ||
} | ||
|
||
auto axes = std::vector<int64_t>(spatial_shape.size(), 0); | ||
std::iota(axes.begin(), axes.end(), 2); | ||
auto axes_const = v0::Constant::create(element::i64, {spatial_shape.size()}, axes); | ||
const auto adaptive_pool = pattern_map.at(a_pool); | ||
std::shared_ptr<Node> res_node; | ||
if (std::dynamic_pointer_cast<v8::AdaptiveAvgPool>(adaptive_pool)) { | ||
res_node = std::make_shared<v1::ReduceMean>(adaptive_pool->input_value(0), axes_const, true); | ||
} else if (std::dynamic_pointer_cast<v8::AdaptiveMaxPool>(adaptive_pool)) { | ||
if (adaptive_pool->outputs().size() > 1 && adaptive_pool->output(1).get_target_inputs().size() != 0) { | ||
// If indexes are used we can't replace it | ||
return false; | ||
} | ||
res_node = std::make_shared<v1::ReduceMax>(adaptive_pool->input_value(0), axes_const, true); | ||
} else { | ||
return false; | ||
} | ||
adaptive_pool->output(0).replace(res_node); | ||
res_node->set_friendly_name(adaptive_pool->get_friendly_name()); | ||
copy_runtime_info(adaptive_pool, res_node); | ||
return true; | ||
}; | ||
|
||
auto m = std::make_shared<ov::pass::pattern::Matcher>(a_pool, matcher_name); | ||
this->register_matcher(m, callback); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
src/common/transformations/tests/common_optimizations/adaptive_pool_to_reduce.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// Copyright (C) 2018-2023 Intel Corporation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
#include <gtest/gtest.h> | ||
|
||
#include <openvino/opsets/opset10.hpp> | ||
#include <transformations/common_optimizations/adaptive_pool_to_reduce.hpp> | ||
|
||
#include "common_test_utils/ngraph_test_utils.hpp" | ||
|
||
using namespace testing; | ||
using namespace ov; | ||
|
||
TEST_F(TransformationTestsF, AdaptiveAvgPool2dToReduceMean) { | ||
{ | ||
auto data = std::make_shared<opset10::Parameter>(element::f32, PartialShape{1, 3, 14, 14}); | ||
auto out_spatial_shape = opset10::Constant::create(element::i32, Shape{2}, {1, 1}); | ||
auto adaptive_pool = std::make_shared<opset10::AdaptiveAvgPool>(data, out_spatial_shape); | ||
auto result = std::make_shared<opset10::Result>(adaptive_pool); | ||
model = std::make_shared<Model>(ResultVector{result}, ParameterVector{data}); | ||
manager.register_pass<pass::AdaptivePoolToReduce>(); | ||
} | ||
{ | ||
auto data = std::make_shared<opset10::Parameter>(element::f32, PartialShape{1, 3, 14, 14}); | ||
auto axes = opset10::Constant::create(element::i64, Shape{2}, {2, 3}); | ||
auto reduce_mean = std::make_shared<opset10::ReduceMean>(data, axes, true); | ||
auto result = std::make_shared<opset10::Result>(reduce_mean); | ||
model_ref = std::make_shared<Model>(ResultVector{result}, ParameterVector{data}); | ||
} | ||
} | ||
|
||
TEST_F(TransformationTestsF, AdaptiveMaxPool2dToReduceMax) { | ||
{ | ||
auto data = std::make_shared<opset10::Parameter>(element::f32, PartialShape{1, 3, 14, 14}); | ||
auto out_spatial_shape = opset10::Constant::create(element::i32, Shape{2}, {1, 1}); | ||
auto adaptive_pool = std::make_shared<opset10::AdaptiveMaxPool>(data, out_spatial_shape); | ||
auto result = std::make_shared<opset10::Result>(adaptive_pool); | ||
model = std::make_shared<Model>(ResultVector{result}, ParameterVector{data}); | ||
manager.register_pass<pass::AdaptivePoolToReduce>(); | ||
} | ||
{ | ||
auto data = std::make_shared<opset10::Parameter>(element::f32, PartialShape{1, 3, 14, 14}); | ||
auto axes = opset10::Constant::create(element::i64, Shape{2}, {2, 3}); | ||
auto reduce_mean = std::make_shared<opset10::ReduceMax>(data, axes, true); | ||
auto result = std::make_shared<opset10::Result>(reduce_mean); | ||
model_ref = std::make_shared<Model>(ResultVector{result}, ParameterVector{data}); | ||
} | ||
} | ||
|
||
TEST_F(TransformationTestsF, AdaptiveMaxPool2dToReduceMaxUsedIndexes) { | ||
{ | ||
auto data = std::make_shared<opset10::Parameter>(element::f32, PartialShape{1, 3, 14, 14}); | ||
auto out_spatial_shape = opset10::Constant::create(element::i32, Shape{2}, {1, 1}); | ||
auto adaptive_pool = std::make_shared<opset10::AdaptiveMaxPool>(data, out_spatial_shape); | ||
auto result1 = std::make_shared<opset10::Result>(adaptive_pool->output(0)); | ||
auto result2 = std::make_shared<opset10::Result>(adaptive_pool->output(1)); | ||
model = std::make_shared<Model>(ResultVector{result1, result2}, ParameterVector{data}); | ||
manager.register_pass<pass::AdaptivePoolToReduce>(); | ||
} | ||
// Reference model equals initial model | ||
} | ||
|
||
TEST_F(TransformationTestsF, AdaptiveAvgPool3dToReduceMean) { | ||
{ | ||
auto data = std::make_shared<opset10::Parameter>(element::f32, PartialShape{1, 3, 14, 14, 14}); | ||
auto out_spatial_shape = opset10::Constant::create(element::i32, Shape{3}, {1, 1, 1}); | ||
auto adaptive_pool = std::make_shared<opset10::AdaptiveAvgPool>(data, out_spatial_shape); | ||
auto result = std::make_shared<opset10::Result>(adaptive_pool); | ||
model = std::make_shared<Model>(ResultVector{result}, ParameterVector{data}); | ||
manager.register_pass<pass::AdaptivePoolToReduce>(); | ||
} | ||
{ | ||
auto data = std::make_shared<opset10::Parameter>(element::f32, PartialShape{1, 3, 14, 14, 14}); | ||
auto axes = opset10::Constant::create(element::i64, Shape{3}, {2, 3, 4}); | ||
auto reduce_mean = std::make_shared<opset10::ReduceMean>(data, axes, true); | ||
auto result = std::make_shared<opset10::Result>(reduce_mean); | ||
model_ref = std::make_shared<Model>(ResultVector{result}, ParameterVector{data}); | ||
} | ||
} | ||
|
||
TEST_F(TransformationTestsF, AdaptiveMaxPool3dToReduceMax) { | ||
{ | ||
auto data = std::make_shared<opset10::Parameter>(element::f32, PartialShape{1, 3, 14, 14, 14}); | ||
auto out_spatial_shape = opset10::Constant::create(element::i32, Shape{3}, {1, 1, 1}); | ||
auto adaptive_pool = std::make_shared<opset10::AdaptiveMaxPool>(data, out_spatial_shape); | ||
auto result = std::make_shared<opset10::Result>(adaptive_pool); | ||
model = std::make_shared<Model>(ResultVector{result}, ParameterVector{data}); | ||
manager.register_pass<pass::AdaptivePoolToReduce>(); | ||
} | ||
{ | ||
auto data = std::make_shared<opset10::Parameter>(element::f32, PartialShape{1, 3, 14, 14, 14}); | ||
auto axes = opset10::Constant::create(element::i64, Shape{3}, {2, 3, 4}); | ||
auto reduce_mean = std::make_shared<opset10::ReduceMax>(data, axes, true); | ||
auto result = std::make_shared<opset10::Result>(reduce_mean); | ||
model_ref = std::make_shared<Model>(ResultVector{result}, ParameterVector{data}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters