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.opset4.ops import mish
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.opset1.ops import multiply
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/mish.hpp"
#include "openvino/op/mod.hpp"
#include "openvino/op/multi_lstm_sequence.hpp"
#include "openvino/op/multiclass_nms.hpp"
#include "openvino/op/multinomial.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(Minimum, 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(Negative, 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_opset11, 177},
OpsetTestParams{ov::get_opset12, 178},
OpsetTestParams{ov::get_opset13, 185}),
OpsetTestParams{ov::get_opset13, 186}),
OpsetTestNameGenerator{});
class MyOpOld : public ov::op::Op {