From 91ce7406ad16b4e4222b64ce908d5e18c1663e6d Mon Sep 17 00:00:00 2001 From: Artur Kulikowski Date: Wed, 10 Aug 2022 13:18:04 +0200 Subject: [PATCH] Remove unused private methods from LSTMSequence (#12397) --- .../include/openvino/op/lstm_sequence.hpp | 23 --- src/core/src/op/lstm_sequence.cpp | 140 ------------------ 2 files changed, 163 deletions(-) diff --git a/src/core/include/openvino/op/lstm_sequence.hpp b/src/core/include/openvino/op/lstm_sequence.hpp index 194a26f49b1..c275f8b626c 100644 --- a/src/core/include/openvino/op/lstm_sequence.hpp +++ b/src/core/include/openvino/op/lstm_sequence.hpp @@ -104,29 +104,6 @@ public: } private: - /// - /// \brief Gets the masked value according to sequence length in a batch. - /// - /// \note Zeros out values or sets them to default value for inputs with - /// sequence length shorter than currently procssed time step. - /// - /// \param[in] data The input value. - /// \param[in] time_step The current time step denoting sequence length. - /// \param[in] batch_axis The batch axis index of data tensor. - /// \param[in] default_value The default value for masked elements. - /// - /// \return The masked value. - /// - std::shared_ptr get_masked_node(const Output& data, - std::int32_t time_step, - std::size_t batch_axis = 0, - const Output& default_value = Output()) const; - - OutputVector lstm_pass(bool is_reverse = false) const; - - // Split(bi-directional) and squeeze input data to remove 'num_direction' dimension. - std::shared_ptr prepare_input(Output node, bool is_reverse, size_t num_direction_axis = 0) const; - std::vector m_activations_alpha; std::vector m_activations_beta; std::vector m_activations; diff --git a/src/core/src/op/lstm_sequence.cpp b/src/core/src/op/lstm_sequence.cpp index b1dac127dbf..f08d7c29f19 100644 --- a/src/core/src/op/lstm_sequence.cpp +++ b/src/core/src/op/lstm_sequence.cpp @@ -149,146 +149,6 @@ shared_ptr op::v0::LSTMSequence::clone_with_new_inputs(const OutputVector& } } -shared_ptr op::v0::LSTMSequence::get_masked_node(const Output& data, - int32_t time_step, - size_t batch_axis, - const Output& default_value) const { - Output mask_value = default_value; - // Create zero mask value node. - if (!mask_value.get_node_shared_ptr()) { - mask_value = opset1::Constant::create(data.get_element_type(), - data.get_shape(), - vector(shape_size(data.get_shape()), 0.f)); - } - - // Create predicate nodes. The condition is whether current time step value - // is greater than sequence length for respective batch inputs. - shared_ptr curr_time_step_node = - opset1::Constant::create(element::i32, - data.get_shape(), - vector(shape_size(data.get_shape()), time_step)); - - Output batch_seq_length = - builder::opset1::legacy_broadcast_for_binary_operation(curr_time_step_node, - input_value(3).get_node_shared_ptr(), - batch_axis); - - // Create mask node deciding whether or not to mask batch data. - shared_ptr mask_condition = make_shared(curr_time_step_node, batch_seq_length); - - // Select values depnding on mask_condition. - // Select(, , ) - return make_shared(mask_condition, mask_value, data); -} - -OutputVector op::v0::LSTMSequence::lstm_pass(bool is_reverse) const { - // ------ VARIABLE'S NAMES AND ACRONYM DEFINITIONS ------ - // The names used below are analogous to the one used in ONNX documentation. - // - // ------ INPUTS ------ - // X - The input tensor. [batch_size, seq_length, input_size] - // W - The weight tensor. [num_directions, 4*hidden_size, input_size] - // R - The recurrence weight tensor. [num_directions, 4*hidden_size, hidden_size] - // B - The bias tensor for input gate. [num_directions, 8*hidden_size] - // P - The weight tensor for peepholes. [num_directions, 3*hidde_size] - // ------ ACRONYMS ------ - // i - input gate - // o - output gate - // f - forget gate - // c - cell gate - // t - time step (t-1 means previous time step) - // ------ VARIABLE NAMES ------ - // H_t - Hidden state vector at current time step. [batch_size, num_directions, hidden_size] - // C_t - Cell state vector at current time step. [batch_size, num_directions, hidden_size] - // h_list - The list of hidden states at all processed time steps. - - NodeVector h_list; - shared_ptr X = input_value(0).get_node_shared_ptr(); - shared_ptr H_t = prepare_input(input_value(1), is_reverse, 1); - shared_ptr C_t = prepare_input(input_value(2), is_reverse, 1); - shared_ptr seq_lengths = input_value(3).get_node_shared_ptr(); - shared_ptr W = prepare_input(input_value(4), is_reverse); - shared_ptr R = prepare_input(input_value(5), is_reverse); - shared_ptr B = prepare_input(input_value(6), is_reverse); - shared_ptr P = prepare_input(input_value(7), is_reverse); - - if (is_reverse) { - X = make_shared(X, seq_lengths, 0 /*batch_axis*/, 1 /*seq_axis*/); - } - - OutputVector in_seqs = builder::opset1::split(X, X->get_shape().at(1), 1); - - for (auto& in_x : in_seqs) { - // Remove empty dim, after above split. - in_x = builder::opset1::squeeze(in_x, {1}); - } - - int32_t time_step{1}; - for (const auto& in_x : in_seqs) { - shared_ptr lstm_cell = make_shared(in_x, - H_t, - C_t, - W, - R, - B, - P, - m_hidden_size, - m_weights_format, - m_activations, - m_activations_alpha, - m_activations_beta, - m_clip_threshold, - m_input_forget); - - Output H = lstm_cell->output(0); - Output C = lstm_cell->output(1); - - // Expand tensors with empty outermost dim, so we can later concatenate - // them. - // Mask hidden state tensor in order to handle mixed sequence lengths. - // This results in zeroing out values in batches with sequence shorter - // than current time_step. - h_list.push_back(get_masked_node(builder::opset1::expand_dims(H, 1), time_step, 0)); - // Reference implementation in ONNX Runtime doesn't mask values of Y_h - // and Y_c outputs, thus here we make sure that only appropriate batches - // (in respect to its sequence length) are updated. Those batches which - // has shorter sequences preserve the last value. - H_t = get_masked_node(H, time_step, 0, H_t); - C_t = get_masked_node(C, time_step, 0, C_t); - time_step++; - } - // The tensor that concats all the intermediate output values of the hidden. - // It has shape [batch_size, seq_length, hidden_size] - shared_ptr Y{make_shared(h_list, 1)}; - - // Get back the original order of the output data. - if (is_reverse) { - Y = make_shared(Y, seq_lengths, 0 /*batch_axis*/, 1 /*seq_axis*/); - } - - // Expand Y so that it has expected shape: - // [batch_size, num_directions, seq_length, hidden_size] - Y = builder::opset1::expand_dims(Y, 1); - - // expand H_t and C_t so that it has expected shape: - // [ batch_size, num_directions, hidden_size] - auto Y_h = builder::opset1::expand_dims(H_t, 1); - auto Y_c = builder::opset1::expand_dims(C_t, 1); - return {Y, Y_h, Y_c}; -} - -shared_ptr op::v0::LSTMSequence::prepare_input(Output node, - bool is_reverse, - size_t num_direction_axis) const { - // In bidirectional mode inputs are stacked together, so we must split them. - Output tmp = node; - if (m_direction == direction::BIDIRECTIONAL) { - tmp = builder::opset1::split(node, 2, num_direction_axis).at(is_reverse ? 1 : 0); - } - // Since we have forward LSTM we can squeeze `num_directions` axis from inputs. - return builder::opset1::squeeze(tmp, {num_direction_axis}); -} - void op::v0::LSTMSequence::validate_and_infer_types() { NGRAPH_OP_SCOPE(v0_LSTMSequence_validate_and_infer_types); for (const auto& input : inputs()) {