diff --git a/src/common/transformations/src/transformations/op_conversions/convert_sequences_to_tensor_iterator.cpp b/src/common/transformations/src/transformations/op_conversions/convert_sequences_to_tensor_iterator.cpp index c10a55a8d91..f2f4b8a57bc 100644 --- a/src/common/transformations/src/transformations/op_conversions/convert_sequences_to_tensor_iterator.cpp +++ b/src/common/transformations/src/transformations/op_conversions/convert_sequences_to_tensor_iterator.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2021 Intel Corporation +// Copyright (C) 2018-2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -87,35 +87,38 @@ namespace { reverse_seq_before = std::make_shared(X, seq_lengths, 0, 1); } + auto axis_0 = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 0 }); + auto axis_1 = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); + // TensorIterator Body: begin auto X_param_pshape = X_pshape; X_param_pshape[1] = 1; // split by seq_lengths dimension auto X_body_param = std::make_shared(X.get_element_type(), X_param_pshape); - auto H_body_param = std::make_shared(H_t.get_element_type(), H_t.get_partial_shape()); + + const auto squeezed_h = ngraph::op::util::make_try_fold(H_t, axis_1); + auto H_body_param = std::make_shared(squeezed_h->get_element_type(), squeezed_h->get_output_partial_shape(0)); auto seq_body_param = std::make_shared(seq_lengths.get_element_type(), seq_lengths.get_partial_shape()); // LSTM sequence case const bool cell_state_defined = C_t.get_node_shared_ptr() != nullptr; - std::shared_ptr C_body_param = cell_state_defined ? - std::make_shared(C_t.get_element_type(), C_t.get_partial_shape()) : - nullptr; - - auto axis_0 = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 0 }); - auto axis_1 = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); + std::shared_ptr C_body_param = nullptr; + std::shared_ptr squeezed_c = nullptr; + if (cell_state_defined) { + squeezed_c = ngraph::op::util::make_try_fold(C_t, axis_1); + C_body_param = std::make_shared(squeezed_c->get_element_type(), squeezed_c->get_output_partial_shape(0)); + } const auto squeezed_x = ngraph::op::util::make_try_fold(X_body_param, axis_1); - const auto squeezed_h = ngraph::op::util::make_try_fold(H_body_param, axis_1); const auto squeezed_w = ngraph::op::util::make_try_fold(W, axis_0); const auto squeezed_r = ngraph::op::util::make_try_fold(R, axis_0); const auto squeezed_b = ngraph::op::util::make_try_fold(B, axis_0); std::shared_ptr cell; if (const auto lstm_sequence = ngraph::as_type_ptr(sequence)) { - const auto squeezed_c = ngraph::op::util::make_try_fold(C_body_param, axis_1); cell = std::make_shared( squeezed_x, - squeezed_h, - squeezed_c, + H_body_param, + C_body_param, squeezed_w, squeezed_r, squeezed_b, @@ -127,7 +130,7 @@ namespace { } else if (const auto rnn_sequence = ngraph::as_type_ptr(sequence)) { cell = std::make_shared( squeezed_x, - squeezed_h, + H_body_param, squeezed_w, squeezed_r, squeezed_b, @@ -139,7 +142,7 @@ namespace { } else if (const auto gnn_sequence = ngraph::as_type_ptr(sequence)) { cell = std::make_shared( squeezed_x, - squeezed_h, + H_body_param, squeezed_w, squeezed_r, squeezed_b, @@ -153,24 +156,24 @@ namespace { ngraph::ParameterVector body_params; ngraph::ResultVector body_results; - auto unsqueeze_dum_dir_h = std::make_shared(cell->output(0), axis_1); - ngraph::Output h_node_to_result = unsqueeze_dum_dir_h; - auto unsqueeze_dum_dir_c = cell_state_defined ? std::make_shared(cell->output(1), axis_1) : nullptr; - ngraph::Output c_node_to_result = cell_state_defined ? unsqueeze_dum_dir_c : ngraph::Output(); + ngraph::Output hidden_state = cell->output(0); + ngraph::Output cell_state; + if (cell_state_defined) + cell_state = cell->output(1); auto tensor_iterator = std::make_shared(); if (enable_mask) { const auto current_iter = get_current_iter(body_params, body_results, seq_body_param); - h_node_to_result = get_masked_value(tensor_iterator, body_params, body_results, current_iter, unsqueeze_dum_dir_h, seq_body_param); + hidden_state = get_masked_value(tensor_iterator, body_params, body_results, current_iter, hidden_state, seq_body_param); if (cell_state_defined) - c_node_to_result = get_masked_value(tensor_iterator, body_params, body_results, current_iter, unsqueeze_dum_dir_c, seq_body_param); + cell_state = get_masked_value(tensor_iterator, body_params, body_results, current_iter, cell_state, seq_body_param); } - auto H_res = std::make_shared(h_node_to_result); - auto C_res = cell_state_defined ? std::make_shared(c_node_to_result) : nullptr; - auto unsqueeze_seq_len = std::make_shared(h_node_to_result, axis_1); - auto concat_res = std::make_shared(unsqueeze_seq_len); + auto H_res = std::make_shared(hidden_state); + auto C_res = cell_state_defined ? std::make_shared(cell_state) : nullptr; + auto hidden_state_unsqueezed = std::make_shared(hidden_state, axis_1); + auto concat_res = std::make_shared(hidden_state_unsqueezed); body_params.push_back(X_body_param); body_params.push_back(H_body_param); @@ -190,21 +193,21 @@ namespace { if (!enable_mask) { // Reversed order, stride -1 tensor_iterator->set_sliced_input(X_body_param, X, -1, -1, 1, 0, 1); - tensor_iterator->get_concatenated_slices(concat_res, -1, -1, 1, 0, 2); + tensor_iterator->get_concatenated_slices(concat_res, -1, -1, 1, 0, 1); } else { // use ReverseSequence as initializer tensor_iterator->set_sliced_input(X_body_param, reverse_seq_before, 0, 1, 1, -1, 1); - tensor_iterator->get_concatenated_slices(concat_res, 0, 1, 1, -1, 2); + tensor_iterator->get_concatenated_slices(concat_res, 0, 1, 1, -1, 1); } } else { // forward order tensor_iterator->set_sliced_input(X_body_param, X, 0, 1, 1, -1, 1); - tensor_iterator->get_concatenated_slices(concat_res, 0, 1, 1, -1, 2); + tensor_iterator->get_concatenated_slices(concat_res, 0, 1, 1, -1, 1); } - tensor_iterator->set_merged_input(H_body_param, H_t, H_res); + tensor_iterator->set_merged_input(H_body_param, squeezed_h, H_res); if (cell_state_defined) - tensor_iterator->set_merged_input(C_body_param, C_t, C_res); + tensor_iterator->set_merged_input(C_body_param, squeezed_c, C_res); tensor_iterator->set_invariant_input(seq_body_param, seq_lengths); ngraph::Output H_out = H_res; @@ -242,8 +245,12 @@ namespace { if (cell_state_defined) tensor_iterator->get_iter_value(C_out); tensor_iterator->set_friendly_name(sequence->get_friendly_name()); + ngraph::NodeVector new_nodes{squeezed_h, tensor_iterator}; + if (cell_state_defined) + new_nodes.push_back(squeezed_c); + ngraph::OutputVector nodes_to_replace; if (enable_mask && is_reverse) { - auto reverse_seq_after = std::make_shared(tensor_iterator->output(0), seq_lengths, 0, 2); + auto reverse_seq_after = std::make_shared(tensor_iterator->output(0), seq_lengths, 0, 1); // Resolve a collision of names data nodes in CNN Network in Reverse case with mask. /* * Before transformation (no collisions) @@ -262,33 +269,31 @@ namespace { * TI [other_name] -- (data_node: other_name.0) --> RevSequence [rnn_name.0] -- (data_node: rnn_name.0) -> Result1 * -- (data_node: other_name.1) --> Identity(rnn_name.1) -- (data_node: rnn_name.1) -> Result2 */ - auto identity_1_h = std::make_shared(tensor_iterator->output(1), axis_1); - auto identity_2_h = std::make_shared(identity_1_h, axis_1); - - ngraph::NodeVector new_nodes{ reverse_seq_after, tensor_iterator, reverse_seq_before, identity_1_h, identity_2_h }; - ngraph::OutputVector nodes_to_replace{ reverse_seq_after, identity_2_h }; + new_nodes.push_back(reverse_seq_before); + new_nodes.push_back(reverse_seq_after); + nodes_to_replace.push_back(reverse_seq_after); + nodes_to_replace.push_back(tensor_iterator->output(1)); if (cell_state_defined) { - auto identity_1_c = std::make_shared(tensor_iterator->output(2), axis_1); - auto identity_2_c = std::make_shared(identity_1_c, axis_1); - - new_nodes.emplace_back(identity_1_c); - new_nodes.emplace_back(identity_2_c); - nodes_to_replace.emplace_back(identity_2_c); - - identity_2_c->set_friendly_name(sequence->get_friendly_name() + ".2"); + auto cell_state = tensor_iterator->output(2); + new_nodes.emplace_back(cell_state.get_node_shared_ptr()); + nodes_to_replace.emplace_back(cell_state); } - ngraph::copy_runtime_info(sequence, new_nodes); - ngraph::replace_node(sequence, nodes_to_replace); - tensor_iterator->set_friendly_name(sequence->get_friendly_name() + "/tensor_iterator"); - reverse_seq_after->set_friendly_name(sequence->get_friendly_name() + ".0"); - identity_2_h->set_friendly_name(sequence->get_friendly_name() + ".1"); } else { - ngraph::copy_runtime_info(sequence, tensor_iterator); - ngraph::replace_node(sequence, tensor_iterator); + nodes_to_replace = tensor_iterator->outputs(); } + + for (size_t i = 0; i < nodes_to_replace.size(); i++) { + auto unsqueeze = std::make_shared(nodes_to_replace[i], axis_1); + unsqueeze->set_friendly_name(sequence->get_friendly_name() + "." + std::to_string(i)); + nodes_to_replace[i] = unsqueeze; + new_nodes.push_back(unsqueeze); + } + ngraph::copy_runtime_info(sequence, new_nodes); + ngraph::replace_node(sequence, nodes_to_replace); + return true; } } // namespace diff --git a/src/tests/functional/inference_engine/transformations/convert_sequences_to_ti_test.cpp b/src/tests/functional/inference_engine/transformations/convert_sequences_to_ti_test.cpp index 48b060d725b..b4eb395cafb 100644 --- a/src/tests/functional/inference_engine/transformations/convert_sequences_to_ti_test.cpp +++ b/src/tests/functional/inference_engine/transformations/convert_sequences_to_ti_test.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2021 Intel Corporation +// Copyright (C) 2018-2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -56,17 +56,17 @@ TEST(TransformationTests, ConvertLSTMSequenceToTensorIterator) { auto X = std::make_shared(element::f32, Shape{ 1, 2, 16 }); auto Y = std::make_shared(element::f32, Shape{ 1, 1, 128 }); auto Z = std::make_shared(element::f32, Shape{ 1, 1, 128 }); + auto squeeze_pattern = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); + auto squeeze_y = std::make_shared(Y, squeeze_pattern); + auto squeeze_z = std::make_shared(Z, squeeze_pattern); auto Xi = std::make_shared(element::f32, Shape{ 1, 1, 16 }); - auto Yi = std::make_shared(element::f32, Shape{ 1, 1, 128 }); - auto Zi = std::make_shared(element::f32, Shape{ 1, 1, 128 }); + auto Yi = std::make_shared(element::f32, Shape{ 1, 128 }); + auto Zi = std::make_shared(element::f32, Shape{ 1, 128 }); auto seq_body_param = std::make_shared(element::i32, PartialShape{ 1 }); // Body - auto squeeze_pattern = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); auto squeeze_x = std::make_shared(Xi, squeeze_pattern); - auto squeeze_y = std::make_shared(Yi, squeeze_pattern); - auto squeeze_z = std::make_shared(Zi, squeeze_pattern); auto w_val = std::vector(512 * 16, 0); auto r_val = std::vector(512 * 128, 0); @@ -75,17 +75,15 @@ TEST(TransformationTests, ConvertLSTMSequenceToTensorIterator) { auto R = ngraph::opset5::Constant::create(ngraph::element::f32, ngraph::Shape{ 512, 128 }, r_val); auto B = ngraph::opset5::Constant::create(ngraph::element::f32, ngraph::Shape{ 512 }, b_val); - auto rnn_cell = std::make_shared(squeeze_x, squeeze_y, squeeze_z, W, R, B, 128); + auto rnn_cell = std::make_shared(squeeze_x, Yi, Zi, W, R, B, 128); auto unsqueeze_pattern = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); - auto unsqueeze1 = std::make_shared(rnn_cell->output(0), unsqueeze_pattern); - auto Ho = std::make_shared(unsqueeze1); + auto Ho = std::make_shared(rnn_cell->output(0)); - auto unsqueeze2 = std::make_shared(unsqueeze1, unsqueeze_pattern); - auto Y_out = std::make_shared(unsqueeze2); + auto unsqueeze_y = std::make_shared(rnn_cell->output(0), unsqueeze_pattern); + auto Y_out = std::make_shared(unsqueeze_y); - auto unsqueeze3 = std::make_shared(rnn_cell->output(1), unsqueeze_pattern); - auto Co = std::make_shared(unsqueeze3); + auto Co = std::make_shared(rnn_cell->output(1)); auto body = std::make_shared(OutputVector{ Y_out, Ho, Co }, ParameterVector{ Xi, Yi, Zi, seq_body_param }); @@ -93,10 +91,10 @@ TEST(TransformationTests, ConvertLSTMSequenceToTensorIterator) { tensor_iterator->set_body(body); tensor_iterator->set_sliced_input(Xi, X, 0, 1, 1, -1, 1); - tensor_iterator->get_concatenated_slices(Y_out, 0, 1, 1, -1, 2); + tensor_iterator->get_concatenated_slices(Y_out, 0, 1, 1, -1, 1); - tensor_iterator->set_merged_input(Yi, Y, Ho); - tensor_iterator->set_merged_input(Zi, Z, Co); + tensor_iterator->set_merged_input(Yi, squeeze_y, Ho); + tensor_iterator->set_merged_input(Zi, squeeze_z, Co); auto seq_lengths = opset5::Constant::create(element::i32, Shape{ 1 }, { 2 }); tensor_iterator->set_invariant_input(seq_body_param, seq_lengths); @@ -104,9 +102,9 @@ TEST(TransformationTests, ConvertLSTMSequenceToTensorIterator) { tensor_iterator->get_iter_value(Ho); tensor_iterator->get_iter_value(Co); - auto res_ti_Y = std::make_shared(tensor_iterator->output(0)); - auto res_ti_H = std::make_shared(tensor_iterator->output(1)); - auto res_ti_C = std::make_shared(tensor_iterator->output(2)); + auto res_ti_Y = std::make_shared(std::make_shared(tensor_iterator->output(0), unsqueeze_pattern)); + auto res_ti_H = std::make_shared(std::make_shared(tensor_iterator->output(1), unsqueeze_pattern)); + auto res_ti_C = std::make_shared(std::make_shared(tensor_iterator->output(2), unsqueeze_pattern)); res_ti_Y->set_friendly_name("Y_out"); res_ti_H->set_friendly_name("Ho"); res_ti_C->set_friendly_name("Co"); @@ -153,17 +151,17 @@ TEST(TransformationTests, ConvertLSTMSequenceToTensorIteratorDynamic) { auto X = std::make_shared(element::f32, PartialShape{ -1, 2, -1 }); auto Y = std::make_shared(element::f32, PartialShape{ 1, 1, 128 }); auto Z = std::make_shared(element::f32, PartialShape{ 1, 1, 128 }); + auto squeeze_pattern = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); + auto squeeze_y = std::make_shared(Y, squeeze_pattern); + auto squeeze_z = std::make_shared(Z, squeeze_pattern); auto Xi = std::make_shared(element::f32, PartialShape{ -1, 1, -1 }); - auto Yi = std::make_shared(element::f32, PartialShape{ 1, 1, 128 }); - auto Zi = std::make_shared(element::f32, PartialShape{ 1, 1, 128 }); + auto Yi = std::make_shared(element::f32, PartialShape{ 1, 128 }); + auto Zi = std::make_shared(element::f32, PartialShape{ 1, 128 }); auto seq_body_param = std::make_shared(element::i32, PartialShape{ 1 }); // Body - auto squeeze_pattern = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); auto squeeze_x = std::make_shared(Xi, squeeze_pattern); - auto squeeze_y = std::make_shared(Yi, squeeze_pattern); - auto squeeze_z = std::make_shared(Zi, squeeze_pattern); auto w_val = std::vector(512 * 16, 0); auto r_val = std::vector(512 * 128, 0); @@ -172,17 +170,15 @@ TEST(TransformationTests, ConvertLSTMSequenceToTensorIteratorDynamic) { auto R = ngraph::opset5::Constant::create(ngraph::element::f32, ngraph::Shape{ 512, 128 }, r_val); auto B = ngraph::opset5::Constant::create(ngraph::element::f32, ngraph::Shape{ 512 }, b_val); - auto rnn_cell = std::make_shared(squeeze_x, squeeze_y, squeeze_z, W, R, B, 128); + auto rnn_cell = std::make_shared(squeeze_x, Yi, Zi, W, R, B, 128); + + auto Ho = std::make_shared(rnn_cell->output(0)); auto unsqueeze_pattern = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); - auto unsqueeze1 = std::make_shared(rnn_cell->output(0), unsqueeze_pattern); - auto Ho = std::make_shared(unsqueeze1); + auto unsqueeze_y = std::make_shared(rnn_cell->output(0), unsqueeze_pattern); + auto Y_out = std::make_shared(unsqueeze_y); - auto unsqueeze2 = std::make_shared(unsqueeze1, unsqueeze_pattern); - auto Y_out = std::make_shared(unsqueeze2); - - auto unsqueeze3 = std::make_shared(rnn_cell->output(1), unsqueeze_pattern); - auto Co = std::make_shared(unsqueeze3); + auto Co = std::make_shared(rnn_cell->output(1)); auto body = std::make_shared(OutputVector{ Y_out, Ho, Co }, ParameterVector{ Xi, Yi, Zi, seq_body_param }); @@ -190,10 +186,10 @@ TEST(TransformationTests, ConvertLSTMSequenceToTensorIteratorDynamic) { tensor_iterator->set_body(body); tensor_iterator->set_sliced_input(Xi, X, 0, 1, 1, -1, 1); - tensor_iterator->get_concatenated_slices(Y_out, 0, 1, 1, -1, 2); + tensor_iterator->get_concatenated_slices(Y_out, 0, 1, 1, -1, 1); - tensor_iterator->set_merged_input(Yi, Y, Ho); - tensor_iterator->set_merged_input(Zi, Z, Co); + tensor_iterator->set_merged_input(Yi, squeeze_y, Ho); + tensor_iterator->set_merged_input(Zi, squeeze_z, Co); auto seq_lengths = opset5::Constant::create(element::i32, Shape{ 1 }, { 2 }); tensor_iterator->set_invariant_input(seq_body_param, seq_lengths); @@ -201,9 +197,9 @@ TEST(TransformationTests, ConvertLSTMSequenceToTensorIteratorDynamic) { tensor_iterator->get_iter_value(Ho); tensor_iterator->get_iter_value(Co); - auto res_ti_Y = std::make_shared(tensor_iterator->output(0)); - auto res_ti_H = std::make_shared(tensor_iterator->output(1)); - auto res_ti_C = std::make_shared(tensor_iterator->output(2)); + auto res_ti_Y = std::make_shared(std::make_shared(tensor_iterator->output(0), unsqueeze_pattern)); + auto res_ti_H = std::make_shared(std::make_shared(tensor_iterator->output(1), unsqueeze_pattern)); + auto res_ti_C = std::make_shared(std::make_shared(tensor_iterator->output(2), unsqueeze_pattern)); res_ti_Y->set_friendly_name("Y_out"); res_ti_H->set_friendly_name("Ho"); res_ti_C->set_friendly_name("Co"); @@ -248,15 +244,15 @@ TEST(TransformationTests, ConvertRNNSequenceToTensorIterator) { { auto X = std::make_shared(element::f32, Shape{ 1, 2, 16 }); auto Y = std::make_shared(element::f32, Shape{ 1, 1, 128 }); + auto squeeze_pattern = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); + auto squeeze_y = std::make_shared(Y, squeeze_pattern); auto Xi = std::make_shared(element::f32, Shape{ 1, 1, 16 }); - auto Yi = std::make_shared(element::f32, Shape{ 1, 1, 128 }); + auto Yi = std::make_shared(element::f32, Shape{ 1, 128 }); auto seq_body_param = std::make_shared(element::i32, PartialShape{ 1 }); // Body - auto squeeze_pattern = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); auto squeeze_x = std::make_shared(Xi, squeeze_pattern); - auto squeeze_y = std::make_shared(Yi, squeeze_pattern); auto w_val = std::vector(128 * 16, 0); auto r_val = std::vector(128 * 128, 0); @@ -265,28 +261,27 @@ TEST(TransformationTests, ConvertRNNSequenceToTensorIterator) { auto R = ngraph::opset5::Constant::create(ngraph::element::f32, ngraph::Shape{ 128, 128 }, r_val); auto B = ngraph::opset5::Constant::create(ngraph::element::f32, ngraph::Shape{ 128 }, b_val); - auto rnn_cell = std::make_shared(squeeze_x, squeeze_y, W, R, B, 128); + auto rnn_cell = std::make_shared(squeeze_x, Yi, W, R, B, 128); auto unsqueeze_pattern = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); - auto unsqueeze1 = std::make_shared(rnn_cell, unsqueeze_pattern); - auto Ho = std::make_shared(unsqueeze1); - auto unsqueeze2 = std::make_shared(unsqueeze1, unsqueeze_pattern); - auto Y_out = std::make_shared(unsqueeze2); + auto Ho = std::make_shared(rnn_cell); + auto unsqueeze = std::make_shared(rnn_cell, unsqueeze_pattern); + auto Y_out = std::make_shared(unsqueeze); auto body = std::make_shared(OutputVector{ Y_out, Ho }, ParameterVector{ Xi, Yi, seq_body_param }); auto tensor_iterator = std::make_shared(); tensor_iterator->set_body(body); tensor_iterator->set_sliced_input(Xi, X, 0, 1, 1, -1, 1); - tensor_iterator->get_concatenated_slices(Y_out, 0, 1, 1, -1, 2); + tensor_iterator->get_concatenated_slices(Y_out, 0, 1, 1, -1, 1); - tensor_iterator->set_merged_input(Yi, Y, Ho); + tensor_iterator->set_merged_input(Yi, squeeze_y, Ho); auto seq_lengths = opset5::Constant::create(element::i32, Shape{ 1 }, { 2 }); tensor_iterator->set_invariant_input(seq_body_param, seq_lengths); tensor_iterator->get_iter_value(Ho); - auto res_ti_Y = std::make_shared(tensor_iterator->output(0)); - auto res_ti_H = std::make_shared(tensor_iterator->output(1)); + auto res_ti_Y = std::make_shared(std::make_shared(tensor_iterator->output(0), unsqueeze_pattern)); + auto res_ti_H = std::make_shared(std::make_shared(tensor_iterator->output(1), unsqueeze_pattern)); res_ti_Y->set_friendly_name("Y_out"); res_ti_H->set_friendly_name("Ho"); @@ -329,15 +324,15 @@ TEST(TransformationTests, ConvertRNNSequenceToTensorIteratorDynamic) { { auto X = std::make_shared(element::f32, PartialShape{ -1, 2, -1 }); auto Y = std::make_shared(element::f32, PartialShape{ 1, 1, 128 }); + auto axis_1 = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); + auto squeeze_y = std::make_shared(Y, axis_1); auto Xi = std::make_shared(element::f32, PartialShape{ -1, 1, -1 }); - auto Yi = std::make_shared(element::f32, PartialShape{ 1, 1, 128 }); + auto Yi = std::make_shared(element::f32, PartialShape{ 1, 128 }); auto seq_body_param = std::make_shared(element::i32, PartialShape{ 1 }); // Body - auto axis_1 = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); auto squeeze_x = std::make_shared(Xi, axis_1); - auto squeeze_y = std::make_shared(Yi, axis_1); auto w_val = std::vector(128 * 16, 0); auto r_val = std::vector(128 * 128, 0); @@ -346,27 +341,26 @@ TEST(TransformationTests, ConvertRNNSequenceToTensorIteratorDynamic) { auto R = ngraph::opset5::Constant::create(ngraph::element::f32, ngraph::Shape{ 128, 128 }, r_val); auto B = ngraph::opset5::Constant::create(ngraph::element::f32, ngraph::Shape{ 128 }, b_val); - auto rnn_cell = std::make_shared(squeeze_x, squeeze_y, W, R, B, 128); - auto unsqueeze1 = std::make_shared(rnn_cell, axis_1); - auto Ho = std::make_shared(unsqueeze1); - auto unsqueeze2 = std::make_shared(unsqueeze1, axis_1); - auto Y_out = std::make_shared(unsqueeze2); + auto rnn_cell = std::make_shared(squeeze_x, Yi, W, R, B, 128); + auto Ho = std::make_shared(rnn_cell); + auto unsqueeze = std::make_shared(rnn_cell, axis_1); + auto Y_out = std::make_shared(unsqueeze); auto body = std::make_shared(OutputVector{ Y_out, Ho }, ParameterVector{ Xi, Yi, seq_body_param }); auto tensor_iterator = std::make_shared(); tensor_iterator->set_body(body); tensor_iterator->set_sliced_input(Xi, X, 0, 1, 1, -1, 1); - tensor_iterator->get_concatenated_slices(Y_out, 0, 1, 1, -1, 2); + tensor_iterator->get_concatenated_slices(Y_out, 0, 1, 1, -1, 1); - tensor_iterator->set_merged_input(Yi, Y, Ho); + tensor_iterator->set_merged_input(Yi, squeeze_y, Ho); auto seq_lengths = opset5::Constant::create(element::i32, Shape{ 1 }, { 2 }); tensor_iterator->set_invariant_input(seq_body_param, seq_lengths); tensor_iterator->get_iter_value(Ho); - auto res_ti_Y = std::make_shared(tensor_iterator->output(0)); - auto res_ti_H = std::make_shared(tensor_iterator->output(1)); + auto res_ti_Y = std::make_shared(std::make_shared(tensor_iterator->output(0), axis_1)); + auto res_ti_H = std::make_shared(std::make_shared(tensor_iterator->output(1), axis_1)); res_ti_Y->set_friendly_name("Y_out"); res_ti_H->set_friendly_name("Ho"); @@ -409,15 +403,15 @@ TEST(TransformationTests, ConvertGRUSequenceToTensorIterator) { { auto X = std::make_shared(element::f32, Shape{ 1, 2, 16 }); auto Y = std::make_shared(element::f32, Shape{ 1, 1, 128 }); + auto squeeze_pattern = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); + auto squeeze_y = std::make_shared(Y, squeeze_pattern); auto Xi = std::make_shared(element::f32, Shape{ 1, 1, 16 }); - auto Yi = std::make_shared(element::f32, Shape{ 1, 1, 128 }); + auto Yi = std::make_shared(element::f32, Shape{ 1, 128 }); auto seq_body_param = std::make_shared(element::i32, PartialShape{ 1 }); // Body - auto squeeze_pattern = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); auto squeeze_x = std::make_shared(Xi, squeeze_pattern); - auto squeeze_y = std::make_shared(Yi, squeeze_pattern); auto w_val = std::vector(384 * 16, 0); auto r_val = std::vector(384 * 128, 0); @@ -426,28 +420,27 @@ TEST(TransformationTests, ConvertGRUSequenceToTensorIterator) { auto R = ngraph::opset5::Constant::create(ngraph::element::f32, ngraph::Shape{ 384, 128 }, r_val); auto B = ngraph::opset5::Constant::create(ngraph::element::f32, ngraph::Shape{ 384 }, b_val); - auto rnn_cell = std::make_shared(squeeze_x, squeeze_y, W, R, B, 128); + auto rnn_cell = std::make_shared(squeeze_x, Yi, W, R, B, 128); + auto Ho = std::make_shared(rnn_cell); auto unsqueeze_pattern = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); - auto unsqueeze1 = std::make_shared(rnn_cell, unsqueeze_pattern); - auto Ho = std::make_shared(unsqueeze1); - auto unsqueeze2 = std::make_shared(unsqueeze1, unsqueeze_pattern); - auto Y_out = std::make_shared(unsqueeze2); + auto unsqueeze = std::make_shared(rnn_cell, unsqueeze_pattern); + auto Y_out = std::make_shared(unsqueeze); auto body = std::make_shared(OutputVector{ Y_out, Ho }, ParameterVector{ Xi, Yi, seq_body_param }); auto tensor_iterator = std::make_shared(); tensor_iterator->set_body(body); tensor_iterator->set_sliced_input(Xi, X, 0, 1, 1, -1, 1); - tensor_iterator->get_concatenated_slices(Y_out, 0, 1, 1, -1, 2); + tensor_iterator->get_concatenated_slices(Y_out, 0, 1, 1, -1, 1); - tensor_iterator->set_merged_input(Yi, Y, Ho); + tensor_iterator->set_merged_input(Yi, squeeze_y, Ho); auto seq_lengths = opset5::Constant::create(element::i32, Shape{ 1 }, { 2 }); tensor_iterator->set_invariant_input(seq_body_param, seq_lengths); tensor_iterator->get_iter_value(Ho); - auto res_ti_Y = std::make_shared(tensor_iterator->output(0)); - auto res_ti_H = std::make_shared(tensor_iterator->output(1)); + auto res_ti_Y = std::make_shared(std::make_shared(tensor_iterator->output(0), unsqueeze_pattern)); + auto res_ti_H = std::make_shared(std::make_shared(tensor_iterator->output(1), unsqueeze_pattern)); res_ti_Y->set_friendly_name("Y_out"); res_ti_H->set_friendly_name("Ho"); @@ -490,15 +483,15 @@ TEST(TransformationTests, ConvertGRUSequenceToTensorIteratorDynamic) { { auto X = std::make_shared(element::f32, PartialShape{ -1, 2, -1 }); auto Y = std::make_shared(element::f32, PartialShape{ 1, 1, 128 }); + auto squeeze_pattern = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); + auto squeeze_y = std::make_shared(Y, squeeze_pattern); auto Xi = std::make_shared(element::f32, PartialShape{ -1, 1, -1 }); - auto Yi = std::make_shared(element::f32, PartialShape{ 1, 1, 128 }); + auto Yi = std::make_shared(element::f32, PartialShape{ 1, 128 }); auto seq_body_param = std::make_shared(element::i32, PartialShape{ 1 }); // Body - auto squeeze_pattern = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); auto squeeze_x = std::make_shared(Xi, squeeze_pattern); - auto squeeze_y = std::make_shared(Yi, squeeze_pattern); auto w_val = std::vector(384 * 16, 0); auto r_val = std::vector(384 * 128, 0); @@ -507,28 +500,27 @@ TEST(TransformationTests, ConvertGRUSequenceToTensorIteratorDynamic) { auto R = ngraph::opset5::Constant::create(ngraph::element::f32, ngraph::Shape{ 384, 128 }, r_val); auto B = ngraph::opset5::Constant::create(ngraph::element::f32, ngraph::Shape{ 384 }, b_val); - auto rnn_cell = std::make_shared(squeeze_x, squeeze_y, W, R, B, 128); + auto rnn_cell = std::make_shared(squeeze_x, Yi, W, R, B, 128); + auto Ho = std::make_shared(rnn_cell); auto unsqueeze_pattern = ngraph::opset5::Constant::create(ngraph::element::i64, ngraph::Shape{ 1 }, { 1 }); - auto unsqueeze1 = std::make_shared(rnn_cell, unsqueeze_pattern); - auto Ho = std::make_shared(unsqueeze1); - auto unsqueeze2 = std::make_shared(unsqueeze1, unsqueeze_pattern); - auto Y_out = std::make_shared(unsqueeze2); + auto unsqueeze = std::make_shared(rnn_cell, unsqueeze_pattern); + auto Y_out = std::make_shared(unsqueeze); auto body = std::make_shared(OutputVector{ Y_out, Ho }, ParameterVector{ Xi, Yi, seq_body_param }); auto tensor_iterator = std::make_shared(); tensor_iterator->set_body(body); tensor_iterator->set_sliced_input(Xi, X, 0, 1, 1, -1, 1); - tensor_iterator->get_concatenated_slices(Y_out, 0, 1, 1, -1, 2); + tensor_iterator->get_concatenated_slices(Y_out, 0, 1, 1, -1, 1); - tensor_iterator->set_merged_input(Yi, Y, Ho); + tensor_iterator->set_merged_input(Yi, squeeze_y, Ho); auto seq_lengths = opset5::Constant::create(element::i32, Shape{ 1 }, { 2 }); tensor_iterator->set_invariant_input(seq_body_param, seq_lengths); tensor_iterator->get_iter_value(Ho); - auto res_ti_Y = std::make_shared(tensor_iterator->output(0)); - auto res_ti_H = std::make_shared(tensor_iterator->output(1)); + auto res_ti_Y = std::make_shared(std::make_shared(tensor_iterator->output(0), unsqueeze_pattern)); + auto res_ti_H = std::make_shared(std::make_shared(tensor_iterator->output(1), unsqueeze_pattern)); res_ti_Y->set_friendly_name("Y_out"); res_ti_H->set_friendly_name("Ho");