Initial commit

This commit is contained in:
p-wysocki 2023-11-16 13:07:49 +01:00
parent f97e7f1c9d
commit 5fd6b521df
6 changed files with 401 additions and 2 deletions

View File

@ -105,7 +105,8 @@ from openvino.runtime.opset1.ops import maximum
from openvino.runtime.opset1.ops import minimum from openvino.runtime.opset1.ops import minimum
from openvino.runtime.opset4.ops import mish from openvino.runtime.opset4.ops import mish
from openvino.runtime.opset1.ops import mod from openvino.runtime.opset1.ops import mod
from openvino.runtime.opset9.ops import multiclass_nms from openvino.runtime.opset13.ops import multi_lstm_sequence
from openvino.runtime.opset9.ops import
from openvino.runtime.opset13.ops import multinomial from openvino.runtime.opset13.ops import multinomial
from openvino.runtime.opset1.ops import multiply from openvino.runtime.opset1.ops import multiply
from openvino.runtime.opset6.ops import mvn from openvino.runtime.opset6.ops import mvn

View File

@ -0,0 +1,176 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
#include "openvino/op/constant.hpp"
#include "openvino/op/lstm_cell.hpp"
#include "openvino/op/util/attr_types.hpp"
#include "openvino/op/util/rnn_cell_base.hpp"
namespace ov {
namespace op {
namespace v0 {
///
/// \brief Class for lstm sequence node.
///
/// \note It follows notation and equations defined as in ONNX standard:
/// https://github.com/onnx/onnx/blob/master/docs/Operators.md#LSTM
///
/// \sa LSTMCell, RNNCell, GRUCell
///
///
/// \ingroup ov_ops_cpp_api
class OPENVINO_API LSTMSequence : public util::RNNCellBase {
public:
OPENVINO_OP("LSTMSequence", "opset1", util::RNNCellBase);
LSTMSequence() = default;
using direction = RecurrentSequenceDirection;
size_t get_default_output_index() const override {
return no_default_index();
}
explicit LSTMSequence(const Output<Node>& X,
const Output<Node>& initial_hidden_state,
const Output<Node>& initial_cell_state,
const Output<Node>& sequence_lengths,
const Output<Node>& W,
const Output<Node>& R,
const Output<Node>& B,
const Output<Node>& P,
const std::int64_t hidden_size,
const direction lstm_direction,
LSTMWeightsFormat weights_format = LSTMWeightsFormat::IFCO,
const std::vector<float> activations_alpha = {},
const std::vector<float> activations_beta = {},
const std::vector<std::string> activations = {"sigmoid", "tanh", "tanh"},
const float clip_threshold = 0,
const bool input_forget = false);
explicit LSTMSequence(const Output<Node>& X,
const Output<Node>& initial_hidden_state,
const Output<Node>& initial_cell_state,
const Output<Node>& sequence_lengths,
const Output<Node>& W,
const Output<Node>& R,
const Output<Node>& B,
const std::int64_t hidden_size,
const direction lstm_direction,
LSTMWeightsFormat weights_format = LSTMWeightsFormat::IFCO,
const std::vector<float>& activations_alpha = {},
const std::vector<float>& activations_beta = {},
const std::vector<std::string>& activations = {"sigmoid", "tanh", "tanh"},
const float clip_threshold = 0,
const bool input_forget = false);
void validate_and_infer_types() override;
bool visit_attributes(AttributeVisitor& visitor) override;
std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& new_args) const override;
std::vector<float> get_activations_alpha() const {
return m_activations_alpha;
}
std::vector<float> get_activations_beta() const {
return m_activations_beta;
}
std::vector<std::string> get_activations() const {
return m_activations;
}
float get_clip_threshold() const {
return m_clip;
}
direction get_direction() const {
return m_direction;
}
void set_direction(const direction& dir) {
m_direction = dir;
}
std::int64_t get_hidden_size() const {
return m_hidden_size;
}
bool get_input_forget() const {
return m_input_forget;
}
LSTMWeightsFormat get_weights_format() const {
return m_weights_format;
}
private:
direction m_direction;
bool m_input_forget;
LSTMWeightsFormat m_weights_format;
};
} // namespace v0
namespace v5 {
///
/// \brief Class for lstm sequence node.
///
/// \note It follows notation and equations defined as in ONNX standard:
/// https://github.com/onnx/onnx/blob/master/docs/Operators.md#LSTM
///
/// \sa LSTMCell, RNNCell, GRUCell
///
///
/// \ingroup ov_ops_cpp_api
class OPENVINO_API LSTMSequence : public util::RNNCellBase {
public:
OPENVINO_OP("LSTMSequence", "opset5", util::RNNCellBase);
LSTMSequence() = default;
using direction = RecurrentSequenceDirection;
size_t get_default_output_index() const override {
return no_default_index();
}
explicit LSTMSequence(const Output<Node>& X,
const Output<Node>& initial_hidden_state,
const Output<Node>& initial_cell_state,
const Output<Node>& sequence_lengths,
const Output<Node>& W,
const Output<Node>& R,
const Output<Node>& B,
const std::int64_t hidden_size,
const direction lstm_direction,
const std::vector<float>& activations_alpha = {},
const std::vector<float>& activations_beta = {},
const std::vector<std::string>& activations = {"sigmoid", "tanh", "tanh"},
const float clip = 0.f)
: RNNCellBase({X, initial_hidden_state, initial_cell_state, sequence_lengths, W, R, B},
hidden_size,
clip,
activations,
activations_alpha,
activations_beta),
m_direction(lstm_direction) {
constructor_validate_and_infer_types();
}
void validate_and_infer_types() override;
bool visit_attributes(AttributeVisitor& visitor) override;
std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& new_args) const override;
direction get_direction() const {
return m_direction;
}
void set_direction(const direction& dir) {
m_direction = dir;
}
private:
direction m_direction{direction::FORWARD};
};
} // namespace v5
} // namespace op
} // namespace ov

View File

@ -109,6 +109,7 @@
#include "openvino/op/minimum.hpp" #include "openvino/op/minimum.hpp"
#include "openvino/op/mish.hpp" #include "openvino/op/mish.hpp"
#include "openvino/op/mod.hpp" #include "openvino/op/mod.hpp"
#include "openvino/op/multi_lstm_sequence.hpp"
#include "openvino/op/multiclass_nms.hpp" #include "openvino/op/multiclass_nms.hpp"
#include "openvino/op/multinomial.hpp" #include "openvino/op/multinomial.hpp"
#include "openvino/op/multiply.hpp" #include "openvino/op/multiply.hpp"

View File

@ -61,6 +61,7 @@ _OPENVINO_OP_REG(MatMul, ov::op::v0)
_OPENVINO_OP_REG(Maximum, ov::op::v1) _OPENVINO_OP_REG(Maximum, ov::op::v1)
_OPENVINO_OP_REG(Minimum, ov::op::v1) _OPENVINO_OP_REG(Minimum, ov::op::v1)
_OPENVINO_OP_REG(Mod, ov::op::v1) _OPENVINO_OP_REG(Mod, ov::op::v1)
_OPENVINO_OP_REG(yMultiLSTMSequence, ov::op::v13)
_OPENVINO_OP_REG(Multiply, ov::op::v1) _OPENVINO_OP_REG(Multiply, ov::op::v1)
_OPENVINO_OP_REG(Negative, ov::op::v0) _OPENVINO_OP_REG(Negative, ov::op::v0)
_OPENVINO_OP_REG(NormalizeL2, ov::op::v0) _OPENVINO_OP_REG(NormalizeL2, ov::op::v0)

View File

@ -0,0 +1,220 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "openvino/op/lstm_sequence.hpp"
#include "itt.hpp"
#include "lstm_sequence_shape_inference.hpp"
#include "openvino/core/attribute_visitor.hpp"
#include "openvino/op/util/recurrent_sequence.hpp"
namespace ov {
op::v0::LSTMSequence::LSTMSequence(const Output<Node>& X,
const Output<Node>& initial_hidden_state,
const Output<Node>& initial_cell_state,
const Output<Node>& sequence_lengths,
const Output<Node>& W,
const Output<Node>& R,
const Output<Node>& B,
const Output<Node>& P,
const std::int64_t hidden_size,
const LSTMSequence::direction lstm_direction,
LSTMWeightsFormat weights_format,
const std::vector<float> activations_alpha,
const std::vector<float> activations_beta,
const std::vector<std::string> activations,
const float clip_threshold,
const bool input_forget)
: RNNCellBase({X, initial_hidden_state, initial_cell_state, sequence_lengths, W, R, B, P},
hidden_size,
clip_threshold,
activations,
activations_alpha,
activations_beta),
m_direction(lstm_direction),
m_input_forget(input_forget),
m_weights_format(weights_format) {
constructor_validate_and_infer_types();
}
op::v0::LSTMSequence::LSTMSequence(const Output<Node>& X,
const Output<Node>& initial_hidden_state,
const Output<Node>& initial_cell_state,
const Output<Node>& sequence_lengths,
const Output<Node>& W,
const Output<Node>& R,
const Output<Node>& B,
const std::int64_t hidden_size,
const LSTMSequence::direction lstm_direction,
LSTMWeightsFormat weights_format,
const std::vector<float>& activations_alpha,
const std::vector<float>& activations_beta,
const std::vector<std::string>& activations,
const float clip_threshold,
const bool input_forget)
: op::v0::LSTMSequence(
X,
initial_hidden_state,
initial_cell_state,
sequence_lengths,
W,
R,
B,
Constant::create(element::f32,
Shape{(lstm_direction == LSTMSequence::direction::BIDIRECTIONAL ? 2UL : 1UL),
3UL * static_cast<size_t>(hidden_size)},
std::vector<float>{0.f}),
hidden_size,
lstm_direction,
weights_format,
activations_alpha,
activations_beta,
activations,
clip_threshold,
input_forget) {}
bool op::v0::LSTMSequence::visit_attributes(AttributeVisitor& visitor) {
OV_OP_SCOPE(v0_LSTMSequence_visit_attributes);
visitor.on_attribute("hidden_size", m_hidden_size);
visitor.on_attribute("activations", m_activations);
visitor.on_attribute("activations_alpha", m_activations_alpha);
visitor.on_attribute("activations_beta", m_activations_beta);
visitor.on_attribute("clip", m_clip);
visitor.on_attribute("direction", m_direction);
visitor.on_attribute("input_forget", m_input_forget);
visitor.on_attribute("weights_format", m_weights_format);
return true;
}
std::shared_ptr<Node> op::v0::LSTMSequence::clone_with_new_inputs(const OutputVector& new_args) const {
OV_OP_SCOPE(v0_LSTMSequence_clone_with_new_inputs);
check_new_args_count(this, new_args);
if (new_args.size() == 8) {
return std::make_shared<op::v0::LSTMSequence>(new_args.at(0), // X
new_args.at(1), // initial_hidden_state
new_args.at(2), // initial_cell_state
new_args.at(3), // sequence_lengths
new_args.at(4), // W
new_args.at(5), // R
new_args.at(6), // B
new_args.at(7), // P
m_hidden_size,
m_direction,
m_weights_format,
m_activations_alpha,
m_activations_beta,
m_activations,
m_clip,
m_input_forget);
} else if (new_args.size() == 7) {
return std::make_shared<op::v0::LSTMSequence>(new_args.at(0), // X
new_args.at(1), // initial_hidden_state
new_args.at(2), // initial_cell_state
new_args.at(3), // sequence_lengths
new_args.at(4), // W
new_args.at(5), // R
new_args.at(6), // B
m_hidden_size,
m_direction,
m_weights_format,
m_activations_alpha,
m_activations_beta,
m_activations,
m_clip,
m_input_forget);
} else {
OPENVINO_THROW("Incorrect number of new arguments");
}
}
void op::v0::LSTMSequence::validate_and_infer_types() {
OV_OP_SCOPE(v0_LSTMSequence_validate_and_infer_types);
auto result_et = element::dynamic;
// Validate input types and save result for output type
NODE_VALIDATION_CHECK(this,
element::Type::merge(result_et, result_et, get_input_element_type(0)) &&
element::Type::merge(result_et, result_et, get_input_element_type(1)) &&
element::Type::merge(result_et, result_et, get_input_element_type(2)) &&
element::Type::merge(result_et, result_et, get_input_element_type(4)) &&
element::Type::merge(result_et, result_et, get_input_element_type(5)) &&
element::Type::merge(result_et, result_et, get_input_element_type(6)),
"Element types for X, initial_hidden_state, initial_cell_state, W, R and B inputs do "
"not match.");
// Mark inputs which are relevant to output parameters
for (size_t i = 0; i <= 6; ++i)
set_input_is_relevant_to_shape(i);
OPENVINO_SUPPRESS_DEPRECATED_START
const auto input_shapes = get_node_input_partial_shapes(*this);
OPENVINO_SUPPRESS_DEPRECATED_END
auto output_shapes = shape_infer(this, input_shapes);
// Set output size, type and shape
set_output_type(0, result_et, output_shapes[0]);
set_output_type(1, result_et, output_shapes[1]);
set_output_type(2, result_et, output_shapes[2]);
}
bool op::v5::LSTMSequence::visit_attributes(AttributeVisitor& visitor) {
OV_OP_SCOPE(v5_LSTMSequence_visit_attributes);
visitor.on_attribute("direction", m_direction);
return op::util::RNNCellBase::visit_attributes(visitor);
}
std::shared_ptr<Node> op::v5::LSTMSequence::clone_with_new_inputs(const OutputVector& new_args) const {
OV_OP_SCOPE(v5_LSTMSequence_clone_with_new_inputs);
check_new_args_count(this, new_args);
if (new_args.size() == 7) {
return std::make_shared<op::v5::LSTMSequence>(new_args.at(0), // X
new_args.at(1), // initial_hidden_state
new_args.at(2), // initial_cell_state
new_args.at(3), // sequence_lengths
new_args.at(4), // W
new_args.at(5), // R
new_args.at(6), // B
m_hidden_size,
m_direction,
m_activations_alpha,
m_activations_beta,
m_activations,
m_clip);
} else {
OPENVINO_THROW("Incorrect number of new arguments");
}
}
void op::v5::LSTMSequence::validate_and_infer_types() {
OV_OP_SCOPE(v5_LSTMSequence_validate_and_infer_types);
auto result_et = element::dynamic;
// Validate input types and save result for output type
NODE_VALIDATION_CHECK(this,
element::Type::merge(result_et, result_et, get_input_element_type(0)) &&
element::Type::merge(result_et, result_et, get_input_element_type(1)) &&
element::Type::merge(result_et, result_et, get_input_element_type(2)) &&
element::Type::merge(result_et, result_et, get_input_element_type(4)) &&
element::Type::merge(result_et, result_et, get_input_element_type(5)) &&
element::Type::merge(result_et, result_et, get_input_element_type(6)),
"Element types for X, initial_hidden_state, initial_cell_state, W, R and B inputs do "
"not match.");
// Mark inputs which are relevant to output parameters
for (size_t i = 0; i <= 6; ++i)
set_input_is_relevant_to_shape(i);
OPENVINO_SUPPRESS_DEPRECATED_START
const auto input_shapes = get_node_input_partial_shapes(*this);
OPENVINO_SUPPRESS_DEPRECATED_END
auto output_shapes = shape_infer(this, input_shapes);
// Set output size, type and shape
set_output_type(0, result_et, output_shapes[0]);
set_output_type(1, result_et, output_shapes[1]);
set_output_type(2, result_et, output_shapes[2]);
}
} // namespace ov

View File

@ -71,7 +71,7 @@ INSTANTIATE_TEST_SUITE_P(opset,
OpsetTestParams{ov::get_opset10, 177}, OpsetTestParams{ov::get_opset10, 177},
OpsetTestParams{ov::get_opset11, 177}, OpsetTestParams{ov::get_opset11, 177},
OpsetTestParams{ov::get_opset12, 178}, OpsetTestParams{ov::get_opset12, 178},
OpsetTestParams{ov::get_opset13, 185}), OpsetTestParams{ov::get_opset13, 186}),
OpsetTestNameGenerator{}); OpsetTestNameGenerator{});
class MyOpOld : public ov::op::Op { class MyOpOld : public ov::op::Op {