[Transformations] Added interchangeable reshape elimination#9691
Conversation
|
@v-Golubev please review the PR |
src/common/transformations/src/transformations/common_optimizations/nop_elimination.cpp
Outdated
Show resolved
Hide resolved
f3fb719 to
53ae67c
Compare
| auto input_node = input.get_node_shared_ptr(); | ||
| if (ov::as_type_ptr<opset3::Squeeze>(input_node) || | ||
| ov::as_type_ptr<opset3::Unsqueeze>(input_node) || | ||
| ov::as_type_ptr<opset3::Reshape>(input_node)) { |
There was a problem hiding this comment.
This check wasn't precise as we don't check the number of consumers here, so we potentially could ruin the model.
There was a problem hiding this comment.
I added check for consumer count in this transformation
| auto input_node = input.get_node_shared_ptr(); | ||
| if (ov::as_type_ptr<opset3::Squeeze>(input_node) || | ||
| ov::as_type_ptr<opset3::Unsqueeze>(input_node) || | ||
| ov::as_type_ptr<opset3::Reshape>(input_node)) { |
There was a problem hiding this comment.
We have dedicated transformation ReshapeSequenceFusion which performs such type of elimination, and this pass doesn't perform this fusion correctly in case of Reshape->Reshape pattern. So I suggest to remove Reshape from this condition.
Also we have to check that number of consumer is equal to 1.
There was a problem hiding this comment.
I added check for consumer count in this transformation and removed Reshape from the condition.
But as I understand, transformation ReshapeSequenceFusion doesn't eliminate redundant reshapes, it always fuses into one reshape. So I updated ReshapeSequenceFusion transformation to cover interchangeable reshapes (to eliminate it)
Thanks!
There was a problem hiding this comment.
Now I'm not sure about Reshape removing from this condition because transformation NopElimination contains EliminationSqueeze and EliminationUnsqueeze that convert Squeeze and Unsqueeze to Reshape. Moreover NopElimination contains EliminationReshape. And if we remove Reshape, using NopElimination we will have pattern Reshape->Reshape after Squeeze->Reshape, for example. Is it ok for NopElimination? What do you think?
| if (!ngraph::op::util::has_op_with_type<ngraph::op::FakeQuantize>(nGraphFunc)) { | ||
| manager.register_pass<ReshapeFullyConnectedFusion>(); | ||
| } | ||
| manager.register_pass<ngraph::pass::EliminateReshape>(); |
There was a problem hiding this comment.
If some transformation inserts such reshapes, so you can simply call this EliminateReshape().apply(reshape) from this pass.
| ASSERT_TRUE(movement_are_missing); | ||
| } | ||
|
|
||
| TEST(nop_elimination, squeeze_unsqueeze_elimination) { |
There was a problem hiding this comment.
I don't insist but in most tests we use TEST_F(TransformationTestsF fixture, so we don't have to check everything manually.
There was a problem hiding this comment.
This file contains only TEST(nop_elimination) so I created test using this fixture. But I decided to create new test for updated transformation ReshapeSequenceFusion (because I added elimination support for redundant reorders) and I used TEST_F(TransformationTestsF fixture for it. Thanks!
53ae67c to
43a5903
Compare
|
|
||
| // eliminate redundant reshape, squeeze, or unsqueeze | ||
| auto input_node = input.get_node_shared_ptr(); | ||
| if (input_node->get_output_size() != 1) |
There was a problem hiding this comment.
It doesn't check the number of consumers, as get_output_size returns number of output ports but not consumers. Please use get_target_inputs after you casted input node to one of this reshape like operations.
There was a problem hiding this comment.
And please add a tests for this.
There was a problem hiding this comment.
I got it, thank you very much!
Added get_output_target_inputs and added test reshape_elimination_v1_check_consumer_count for this case.
| if (input.get_node_shared_ptr()->get_output_partial_shape(0).is_static() && reshape->get_output_partial_shape(0).is_static() && | ||
| input.get_node_shared_ptr()->get_output_shape(0) == reshape->get_output_shape(0)) { | ||
| return replace_output_update_name(reshape->output(0), input); | ||
| } else { | ||
| reshape->input(0).replace_source_output(input); | ||
| copy_runtime_info(nodes, reshape); | ||
| } |
There was a problem hiding this comment.
Input is already an Output class so you can get partial shape from it.
Also as this transformation is included into MOC pipeline where we can rely on shapes only in case if use_shape is true, so we have to parametrize transformation (for example: https://github.com/openvinotoolkit/openvino/blob/master/src/common/transformations/include/transformations/common_optimizations/split_concat_pair_to_interpolate_fusion.hpp#L32 )
| if (input.get_node_shared_ptr()->get_output_partial_shape(0).is_static() && reshape->get_output_partial_shape(0).is_static() && | |
| input.get_node_shared_ptr()->get_output_shape(0) == reshape->get_output_shape(0)) { | |
| return replace_output_update_name(reshape->output(0), input); | |
| } else { | |
| reshape->input(0).replace_source_output(input); | |
| copy_runtime_info(nodes, reshape); | |
| } | |
| bool replaced = false; | |
| if (use_shapes && input.get_partial_shape().is_static() && reshape->get_output_partial_shape(0).is_static() && | |
| input.get_shape() == reshape->get_output_shape(0)) { | |
| // in case if elimination is not allowed we still can eliminate all transposes except last one | |
| replaced = replace_output_update_name(reshape->output(0), input)); | |
| } | |
| if (!replaced) { | |
| reshape->input(0).replace_source_output(input); | |
| copy_runtime_info(nodes, reshape); | |
| } |
Also please add tests for this case.
There was a problem hiding this comment.
Thank you for the explanation!
Done.
About test - Before I added test ReshapeSequenceFusionEliminate that covers case when we can remove 2 redundant reorders. I think it's enough
7bace72 to
365386b
Compare
5c92007 to
ab1ffc4
Compare
|
@GlebKazantaev take a look one more time please |
ab1ffc4 to
642822f
Compare
| copy_runtime_info(nodes, reshape); | ||
| } | ||
|
|
||
| return false; |
There was a problem hiding this comment.
| return false; | |
| return true; |
|
|
||
| if (!replaced) { | ||
| reshape->input(0).replace_source_output(input); | ||
| copy_runtime_info(nodes, reshape); |
There was a problem hiding this comment.
| copy_runtime_info(nodes, reshape); | |
| copy_runtime_info(nodes, reshape); | |
| return false; // because root node wasn't replaced |
| public: | ||
| NGRAPH_RTTI_DECLARATION; | ||
| ReshapeSequenceFusion(); | ||
| ReshapeSequenceFusion(bool use_shape_for_elimination = true); |
There was a problem hiding this comment.
Please update moc_transformations.cpp
https://github.com/openvinotoolkit/openvino/blob/master/src/common/transformations/src/transformations/common_optimizations/moc_transformations.cpp#L156
common_fusions->add_matcher<ngraph::pass::ReshapeSequenceFusion>(m_use_shapes);|
In general LGTM, just some small comments remaining and we can merge. |
642822f to
e81d505
Compare
Details:
Reshape,Squeeze,Unsqueeze).Tickets: