GRU/RNN/LSTM sequence ops, reference implementations, single layer tests (#1594)
* gru/rnn sequences * update gru/rnn sequences ops, add unit tests * enable sequence transformations for cpu plugin * ngraph codestyle * update tensor iterator to rnn/gru/lstm sequence transformations, add unit tests * ngraph codestyle * add visitors for ngraph ie ops, fix a bug with incorrect axis, fix ngraph to ngraph ie conversion * update GRUSequence/GRUSequenceIE according to plugin format * fix ngraph ie implementations according to plugins restricrictions * fix naming issue * adapt unit tests to accordance to new changes * strict checks, additional unit tests * add descriptions for transformations, fix unit tests * enable ti to sequnece and unroll transformations in plugins for testing * disable tensor iterator ngraph reader tests * delete unnecessary cmake file * fix includes * clean up, resolve review comments * move ti to sequence transformation to ti folder * validate_and_infer_types() implementation * input parameter validation for LSTM, GRU and RNN * style-check applied * Add LSTMSequence dynamic shape validation and test props for RNNCell, GRUCell, LSTMCell and LSTMSequence. * recurrent_sequence.hpp moved to ngraph/core/include/ngraph/op/util/ * style check applied * removed unused variable from LSTMSequence::validate_and_infer_types * Add missing newline mark at the end of file. * Add supression macro for FusedOp deprecation. * Add element type initialization * transpose,rnn cell reference implementations * Apply PR review remarks * reference implementations for cells op, single layer tests, align lstm cell/sequence according to the spec * lstm/gru/rnn cell decompostion transformations * ngraph codestyle * clean up * ngraph code style * change inheritance of Cells, fix build * fix build * fix build again * remove Peepholes from LSTMSeq, fix copy_runtime_info in transformations * Rewrite tests to use gtest exception assertions. * resolve tests issues * ngraph codestyle * add missed files * fix typeprop tests * fix lstm sequence checks * fix arm build * fix arm again * delete unnecessary file * add convert weghts format function, enable lstm test, resolve review comments * add ngraph builders * ngraph codestyle * fix unit tests * revert transpose reference implementation * move ti to sequences transformation to another branch, resolve review comments * resolve review comments * revert fix in ie_layer_validators * revert LSTM Cell v0, add LSTMCell v1, update transformation lstm_cell_to_cell_ie * v1 version of LSTMCell op * LSTMSequence v1 operation, exclude LSTMSeq from opset4 * fix python api tests * resolve review comments, tests for decomposition transformations, switch lstm cell to opset4 in mo * references impl for RNN/GRU/LSTM Sequences, single layer tests, bidirectional transformation * fix unit tests * process dynamic ranks of rnn/gru/lstm ops * remove sequences specifications from opset4 * resolve review comments * fix validate_and_infer_types of GRU/RNN sequences Co-authored-by: Szymon Durawa <szymon.durawa@intel.com>
This commit is contained in:
@@ -85,15 +85,15 @@ TEST(ConvertFunctionToCNNNetworkTests, OpsShouldBeConvertedToIERepresentation) {
|
||||
std::make_shared<ngraph::opset4::GroupConvolution>(),
|
||||
std::make_shared<ngraph::opset4::GroupConvolutionBackpropData>(),
|
||||
std::make_shared<ngraph::opset4::GRUCell>(),
|
||||
// std::make_shared<ngraph::opset4::GRUSequence>(), todo: enable after GRUSequence support
|
||||
// std::make_shared<ngraph::op::v5::GRUSequence>(), todo: enable after GRUSequence support
|
||||
std::make_shared<ngraph::opset4::HardSigmoid>(),
|
||||
std::make_shared<ngraph::opset4::LRN>(),
|
||||
std::make_shared<ngraph::opset4::LSTMCell>(),
|
||||
// std::make_shared<ngraph::opset4::LSTMSequence>(), todo: enable after LSTMSequence support
|
||||
// std::make_shared<ngraph::op::v5::LSTMSequence>(), todo: enable after LSTMSequence support
|
||||
std::make_shared<ngraph::opset4::NonMaxSuppression>(),
|
||||
std::make_shared<ngraph::opset4::NormalizeL2>(),
|
||||
std::make_shared<ngraph::opset4::RNNCell>(),
|
||||
// std::make_shared<ngraph::opset4::RNNSequence>(), todo: enable after RNNSequence support
|
||||
// std::make_shared<ngraph::op::v5::RNNSequence>(), todo: enable after RNNSequence support
|
||||
std::make_shared<ngraph::opset4::OneHot>(),
|
||||
std::make_shared<ngraph::opset4::Pad>(),
|
||||
std::make_shared<ngraph::opset4::PriorBoxClustered>(),
|
||||
|
||||
@@ -0,0 +1,271 @@
|
||||
// Copyright (C) 2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include <transformations/init_node_info.hpp>
|
||||
#include <transformations/convert_opset1_to_legacy/convert_sequences_to_sequences_ie.hpp>
|
||||
|
||||
#include <ngraph/ops.hpp>
|
||||
#include <ngraph/opsets/opset4.hpp>
|
||||
#include <ngraph/function.hpp>
|
||||
#include <ngraph_ops/gru_sequence_ie.hpp>
|
||||
#include <ngraph_ops/rnn_sequence_ie.hpp>
|
||||
#include <ngraph_ops/lstm_sequence_ie.hpp>
|
||||
#include <ngraph/pass/manager.hpp>
|
||||
|
||||
#include "common_test_utils/test_common.hpp"
|
||||
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||
|
||||
using namespace testing;
|
||||
|
||||
TEST(TransformationTests, GRUSequenceConversionTest) {
|
||||
std::shared_ptr<ngraph::Function> f(nullptr), f_ref(nullptr);
|
||||
std::shared_ptr<ngraph::op::v5::GRUSequence> sequence;
|
||||
|
||||
const size_t batch_size = 2;
|
||||
const size_t input_size = 3;
|
||||
const size_t hidden_size = 3;
|
||||
const size_t gates_count = 3;
|
||||
const size_t num_directions = 1;
|
||||
{
|
||||
const auto X = std::make_shared<ngraph::opset4::Parameter>(ngraph::element::f32,
|
||||
ngraph::Shape{batch_size, 1, input_size});
|
||||
const auto W =
|
||||
std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32,
|
||||
ngraph::Shape{num_directions, gates_count * hidden_size, input_size});
|
||||
const auto R =
|
||||
std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32,
|
||||
ngraph::Shape{num_directions, gates_count * hidden_size, hidden_size});
|
||||
const auto H_t = std::make_shared<ngraph::opset4::Parameter>(ngraph::element::f32,
|
||||
ngraph::Shape{batch_size, num_directions, hidden_size});
|
||||
const auto B = std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32,
|
||||
ngraph::Shape{num_directions, gates_count * hidden_size});
|
||||
|
||||
const auto seq_len = std::make_shared<ngraph::opset4::Constant>(ngraph::element::i32, ngraph::Shape{batch_size});
|
||||
sequence = std::make_shared<ngraph::op::v5::GRUSequence>(X, H_t, seq_len, W, R, B, hidden_size,
|
||||
ngraph::op::RecurrentSequenceDirection::FORWARD);
|
||||
sequence->set_friendly_name("test_sequence");
|
||||
|
||||
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{sequence}, ngraph::ParameterVector{X, H_t});
|
||||
ngraph::pass::Manager manager;
|
||||
manager.register_pass<ngraph::pass::InitNodeInfo>();
|
||||
manager.register_pass<ngraph::pass::ConvertGRUSequenceMatcher>();
|
||||
manager.run_passes(f);
|
||||
ASSERT_NO_THROW(check_rt_info(f));
|
||||
}
|
||||
|
||||
{
|
||||
const auto X = std::make_shared<ngraph::opset4::Parameter>(ngraph::element::f32,
|
||||
ngraph::Shape{batch_size, 1, input_size});
|
||||
const auto W =
|
||||
std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32,
|
||||
ngraph::Shape{num_directions, gates_count * hidden_size, input_size});
|
||||
const auto R =
|
||||
std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32,
|
||||
ngraph::Shape{num_directions, gates_count * hidden_size, hidden_size});
|
||||
const auto H_t = std::make_shared<ngraph::opset4::Parameter>(ngraph::element::f32,
|
||||
ngraph::Shape{batch_size, num_directions, hidden_size});
|
||||
const auto B = std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32,
|
||||
ngraph::Shape{num_directions, gates_count * hidden_size});
|
||||
|
||||
const auto seq_len = std::make_shared<ngraph::opset4::Constant>(ngraph::element::i32, ngraph::Shape{batch_size}, 1);
|
||||
auto axis_1 = ngraph::opset4::Constant::create(ngraph::element::i64, ngraph::Shape{1}, {1});
|
||||
auto in_1 = std::make_shared<ngraph::opset4::Squeeze>(H_t, axis_1);
|
||||
auto concat = std::make_shared<ngraph::opset4::Concat>(ngraph::NodeVector({W, R}), 2);
|
||||
auto axis_2 = ngraph::opset4::Constant::create(ngraph::element::i64, ngraph::Shape{1}, {0});
|
||||
auto in_3 = std::make_shared<ngraph::opset4::Squeeze>(concat->output(0), axis_2);
|
||||
auto in_4 = std::make_shared<ngraph::opset4::Squeeze>(B, axis_2);
|
||||
auto sequence_ie = std::make_shared<ngraph::op::GRUSequenceIE>(X,
|
||||
in_1,
|
||||
seq_len, // this input is not supported
|
||||
in_3,
|
||||
in_4,
|
||||
sequence->get_hidden_size(),
|
||||
sequence->get_direction(),
|
||||
sequence->get_activations(),
|
||||
sequence->get_activations_alpha(),
|
||||
sequence->get_activations_beta(),
|
||||
sequence->get_clip(),
|
||||
sequence->get_linear_before_reset());
|
||||
sequence_ie->set_friendly_name("test_sequence");
|
||||
|
||||
auto unsqueeze_axis = ngraph::opset4::Constant::create(ngraph::element::i64, ngraph::Shape{1}, {1});
|
||||
auto unsqueeze_1 = std::make_shared<ngraph::opset4::Unsqueeze>(sequence_ie->output(0), unsqueeze_axis);
|
||||
auto unsqueeze_2 = std::make_shared<ngraph::opset4::Unsqueeze>(sequence_ie->output(1), unsqueeze_axis);
|
||||
f_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{unsqueeze_1}, ngraph::ParameterVector{X, H_t});
|
||||
}
|
||||
auto res = compare_functions(f, f_ref);
|
||||
ASSERT_TRUE(res.first) << res.second;
|
||||
|
||||
auto result_node_of_converted_f = f->get_output_op(0);
|
||||
auto sequence_node = result_node_of_converted_f->input_value(0).get_node_shared_ptr()
|
||||
->input_value(0).get_node_shared_ptr();
|
||||
}
|
||||
|
||||
TEST(TransformationTests, RNNSequenceConversionTest) {
|
||||
const size_t hidden_size = 3;
|
||||
const size_t num_directions = 1;
|
||||
const size_t batch_size = 2;
|
||||
std::shared_ptr<ngraph::Function> f(nullptr), f_ref(nullptr);
|
||||
std::shared_ptr<ngraph::op::v5::RNNSequence> sequence;
|
||||
|
||||
{
|
||||
auto X = std::make_shared<ngraph::opset4::Parameter>(ngraph::element::f32, ngraph::Shape{batch_size, 1, 3});
|
||||
auto H = std::make_shared<ngraph::opset4::Parameter>(ngraph::element::f32, ngraph::Shape{batch_size, num_directions, 3});
|
||||
auto W = std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32, ngraph::Shape{num_directions, 3, 3});
|
||||
auto R = std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32, ngraph::Shape{num_directions, 3, 3});
|
||||
auto B = std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32, ngraph::Shape{num_directions, 3});
|
||||
auto seq_len = std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32, ngraph::Shape{2});
|
||||
sequence = std::make_shared<ngraph::op::v5::RNNSequence>(X, H, seq_len, W, R, B, hidden_size,
|
||||
ngraph::op::RecurrentSequenceDirection::FORWARD);
|
||||
sequence->set_friendly_name("test_sequence");
|
||||
|
||||
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{sequence}, ngraph::ParameterVector{X, H});
|
||||
ngraph::pass::Manager manager;
|
||||
manager.register_pass<ngraph::pass::InitNodeInfo>();
|
||||
manager.register_pass<ngraph::pass::ConvertRNNSequenceMatcher>();
|
||||
manager.run_passes(f);
|
||||
ASSERT_NO_THROW(check_rt_info(f));
|
||||
}
|
||||
|
||||
{
|
||||
auto X = std::make_shared<ngraph::opset4::Parameter>(ngraph::element::f32, ngraph::Shape{batch_size, 1, 3});
|
||||
auto H = std::make_shared<ngraph::opset4::Parameter>(ngraph::element::f32, ngraph::Shape{batch_size, num_directions, 3});
|
||||
auto W = std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32, ngraph::Shape{num_directions, 3, 3});
|
||||
auto R = std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32, ngraph::Shape{num_directions, 3, 3});
|
||||
auto B = std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32, ngraph::Shape{num_directions, 3});
|
||||
auto seq_len = std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32, ngraph::Shape{batch_size}, 1);
|
||||
auto axis_1 = ngraph::opset4::Constant::create(ngraph::element::i64, ngraph::Shape{1}, {1});
|
||||
auto in_1 = std::make_shared<ngraph::opset4::Squeeze>(H, axis_1);
|
||||
auto concat = std::make_shared<ngraph::opset4::Concat>(ngraph::NodeVector({W, R}), 2);
|
||||
auto axis_2 = ngraph::opset4::Constant::create(ngraph::element::i64, ngraph::Shape{1}, {0});
|
||||
auto in_3 = std::make_shared<ngraph::opset4::Squeeze>(concat->output(0), axis_2);
|
||||
auto in_4 = std::make_shared<ngraph::opset4::Squeeze>(B, axis_2);
|
||||
auto sequence_ie = std::make_shared<ngraph::op::RNNSequenceIE>(X,
|
||||
in_1,
|
||||
seq_len,
|
||||
in_3,
|
||||
in_4,
|
||||
sequence->get_hidden_size(),
|
||||
sequence->get_direction(),
|
||||
sequence->get_activations(),
|
||||
sequence->get_activations_alpha(),
|
||||
sequence->get_activations_beta(),
|
||||
sequence->get_clip());
|
||||
|
||||
auto unsqueeze_axis = ngraph::opset4::Constant::create(ngraph::element::i64, ngraph::Shape{1}, {1});
|
||||
auto unsqueeze_1 = std::make_shared<ngraph::opset4::Unsqueeze>(sequence_ie->output(0), unsqueeze_axis);
|
||||
auto unsqueeze_2 = std::make_shared<ngraph::opset4::Unsqueeze>(sequence_ie->output(1), unsqueeze_axis);
|
||||
sequence_ie->set_friendly_name("test_sequence");
|
||||
f_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{unsqueeze_1}, ngraph::ParameterVector{X, H});
|
||||
}
|
||||
|
||||
auto res = compare_functions(f, f_ref);
|
||||
ASSERT_TRUE(res.first) << res.second;
|
||||
|
||||
auto result_node_of_converted_f = f->get_output_op(0);
|
||||
auto sequence_node = result_node_of_converted_f->input_value(0).get_node_shared_ptr()
|
||||
->input_value(0).get_node_shared_ptr();
|
||||
}
|
||||
|
||||
TEST(TransformationTests, LSTMSequenceConversionTest) {
|
||||
const size_t batch_size = 2;
|
||||
const size_t input_size = 3;
|
||||
const size_t hidden_size = 3;
|
||||
const size_t gates_count = 4;
|
||||
const size_t num_directions = 1;
|
||||
std::shared_ptr<ngraph::Function> f(nullptr), f_ref(nullptr);
|
||||
std::shared_ptr<ngraph::op::v5::LSTMSequence> sequence;
|
||||
{
|
||||
const auto X = std::make_shared<ngraph::opset4::Parameter>(ngraph::element::f32,
|
||||
ngraph::Shape{batch_size, 10, input_size});
|
||||
const auto W =
|
||||
std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32,
|
||||
ngraph::Shape{num_directions,
|
||||
gates_count * hidden_size, input_size});
|
||||
const auto R =
|
||||
std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32,
|
||||
ngraph::Shape{num_directions,
|
||||
gates_count * hidden_size, hidden_size});
|
||||
const auto H_t = std::make_shared<ngraph::opset4::Parameter>(ngraph::element::f32,
|
||||
ngraph::Shape{batch_size, num_directions,
|
||||
hidden_size});
|
||||
const auto C_t = std::make_shared<ngraph::opset4::Parameter>(ngraph::element::f32,
|
||||
ngraph::Shape{batch_size, num_directions, hidden_size});
|
||||
const auto B = std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32,
|
||||
ngraph::Shape{num_directions,
|
||||
gates_count * hidden_size});
|
||||
const auto seq_len = std::make_shared<ngraph::opset4::Constant>(ngraph::element::i32, ngraph::Shape{batch_size});
|
||||
sequence = std::make_shared<ngraph::op::v5::LSTMSequence>(X, H_t, C_t, seq_len, W, R, B, hidden_size,
|
||||
ngraph::op::RecurrentSequenceDirection::FORWARD);
|
||||
sequence->set_friendly_name("test_sequence");
|
||||
|
||||
f = std::make_shared<ngraph::Function>(ngraph::OutputVector{sequence->output(0)}, ngraph::ParameterVector{X, H_t, C_t});
|
||||
ngraph::pass::Manager manager;
|
||||
manager.register_pass<ngraph::pass::InitNodeInfo>();
|
||||
manager.register_pass<ngraph::pass::ConvertLSTMSequenceMatcher>();
|
||||
manager.run_passes(f);
|
||||
ASSERT_NO_THROW(check_rt_info(f));
|
||||
}
|
||||
|
||||
{
|
||||
const auto X = std::make_shared<ngraph::opset4::Parameter>(ngraph::element::f32,
|
||||
ngraph::Shape{batch_size, 10, input_size});
|
||||
const auto W =
|
||||
std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32,
|
||||
ngraph::Shape{num_directions,
|
||||
gates_count * hidden_size, input_size});
|
||||
const auto R =
|
||||
std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32,
|
||||
ngraph::Shape{num_directions,
|
||||
gates_count * hidden_size, hidden_size});
|
||||
const auto H_t = std::make_shared<ngraph::opset4::Parameter>(ngraph::element::f32,
|
||||
ngraph::Shape{batch_size, num_directions, hidden_size});
|
||||
const auto C_t = std::make_shared<ngraph::opset4::Parameter>(ngraph::element::f32,
|
||||
ngraph::Shape{batch_size, num_directions, hidden_size});
|
||||
const auto seq_lenghts = std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32,
|
||||
ngraph::Shape{batch_size});
|
||||
const auto B = std::make_shared<ngraph::opset4::Constant>(ngraph::element::f32,
|
||||
ngraph::Shape{num_directions,
|
||||
gates_count * hidden_size});
|
||||
// const auto seq_len = std::make_shared<ngraph::opset4::Constant>(ngraph::element::i32, ngraph::Shape{1}, 1);
|
||||
auto axis_1 = ngraph::opset4::Constant::create(ngraph::element::i64, ngraph::Shape{1}, {1});
|
||||
auto in_1 = std::make_shared<ngraph::opset4::Squeeze>(H_t, axis_1);
|
||||
auto in_2 = std::make_shared<ngraph::opset4::Squeeze>(C_t, axis_1);
|
||||
auto concat = std::make_shared<ngraph::opset4::Concat>(ngraph::NodeVector({W, R}), 2);
|
||||
auto axis_2 = ngraph::opset4::Constant::create(ngraph::element::i64, ngraph::Shape{1}, {0});
|
||||
auto in_3 = std::make_shared<ngraph::opset4::Squeeze>(concat->output(0), axis_2);
|
||||
auto in_4 = std::make_shared<ngraph::opset4::Squeeze>(B, axis_2);
|
||||
auto sequence_ie = std::make_shared<ngraph::op::LSTMSequenceIE>(X,
|
||||
in_1,
|
||||
in_2,
|
||||
seq_lenghts,
|
||||
in_3,
|
||||
in_4,
|
||||
sequence->get_hidden_size(),
|
||||
sequence->get_direction(),
|
||||
sequence->get_activations(),
|
||||
sequence->get_activations_alpha(),
|
||||
sequence->get_activations_beta(),
|
||||
sequence->get_clip());
|
||||
sequence_ie->set_friendly_name("test_sequence");
|
||||
auto unsqueeze_axis = ngraph::opset4::Constant::create(ngraph::element::i64, ngraph::Shape{1}, {1});
|
||||
auto unsqueeze_1 = std::make_shared<ngraph::opset4::Unsqueeze>(sequence_ie->output(0), unsqueeze_axis);
|
||||
auto unsqueeze_2 = std::make_shared<ngraph::opset4::Unsqueeze>(sequence_ie->output(1), unsqueeze_axis);
|
||||
auto unsqueeze_3 = std::make_shared<ngraph::opset4::Unsqueeze>(sequence_ie->output(2), unsqueeze_axis);
|
||||
f_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{unsqueeze_1},
|
||||
ngraph::ParameterVector{X, H_t, C_t});
|
||||
}
|
||||
|
||||
auto res = compare_functions(f, f_ref);
|
||||
ASSERT_TRUE(res.first) << res.second;
|
||||
|
||||
auto result_node_of_converted_f = f->get_output_op(0);
|
||||
auto sequence_node = result_node_of_converted_f->input_value(0).get_node_shared_ptr()
|
||||
->input_value(0).get_node_shared_ptr();
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2019 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
#include <ngraph/op/util/attr_types.hpp>
|
||||
#include "single_layer_tests/gru_sequence.hpp"
|
||||
#include "common_test_utils/test_constants.hpp"
|
||||
|
||||
using namespace LayerTestsDefinitions;
|
||||
|
||||
namespace {
|
||||
// without clip values increase rapidly, so use only seq_lenghts = 2
|
||||
std::vector<size_t> seq_lengths_zero_clip{2};
|
||||
std::vector<size_t> seq_lengths_clip_non_zero{20};
|
||||
std::vector<size_t> batch{1, 10};
|
||||
std::vector<size_t> hidden_size{1, 10};
|
||||
std::vector<size_t> input_size{10};
|
||||
std::vector<std::vector<std::string>> activations = {{"relu", "tanh"}, {"tanh", "sigmoid"}, {"sigmoid", "tanh"},
|
||||
{"tanh", "relu"}};
|
||||
std::vector<bool> linear_before_reset = {true, false};
|
||||
std::vector<float> clip{0.f};
|
||||
std::vector<float> clip_non_zeros{0.7f};
|
||||
std::vector<ngraph::op::RecurrentSequenceDirection> direction = {ngraph::op::RecurrentSequenceDirection::FORWARD,
|
||||
ngraph::op::RecurrentSequenceDirection::REVERSE,
|
||||
ngraph::op::RecurrentSequenceDirection::BIDIRECTIONAL
|
||||
};
|
||||
std::vector<InferenceEngine::Precision> netPrecisions = {InferenceEngine::Precision::FP32,
|
||||
InferenceEngine::Precision::FP16};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(GRUSequenceCommonZeroClip, GRUSequenceTest,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(seq_lengths_zero_clip),
|
||||
::testing::ValuesIn(batch),
|
||||
::testing::ValuesIn(hidden_size),
|
||||
::testing::ValuesIn(input_size),
|
||||
::testing::ValuesIn(activations),
|
||||
::testing::ValuesIn(clip),
|
||||
::testing::ValuesIn(linear_before_reset),
|
||||
::testing::ValuesIn(direction),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||
GRUSequenceTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(GRUSequenceCommonClip, GRUSequenceTest,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(seq_lengths_clip_non_zero),
|
||||
::testing::ValuesIn(batch),
|
||||
::testing::ValuesIn(hidden_size),
|
||||
::testing::ValuesIn(input_size),
|
||||
::testing::ValuesIn(activations),
|
||||
::testing::ValuesIn(clip_non_zeros),
|
||||
::testing::ValuesIn(linear_before_reset),
|
||||
::testing::ValuesIn(direction),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||
GRUSequenceTest::getTestCaseName);
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright (C) 2019 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
#include <ngraph/op/util/attr_types.hpp>
|
||||
#include "single_layer_tests/lstm_sequence.hpp"
|
||||
#include "common_test_utils/test_constants.hpp"
|
||||
|
||||
using namespace LayerTestsDefinitions;
|
||||
|
||||
namespace {
|
||||
// without clip values increase rapidly, so use only seq_lenghts = 2
|
||||
std::vector<size_t> seq_lengths_zero_clip{2};
|
||||
std::vector<size_t> seq_lengths_clip_non_zero{20};
|
||||
std::vector<size_t> batch{1, 10};
|
||||
std::vector<size_t> hidden_size{1, 10};
|
||||
std::vector<size_t> input_size{10};
|
||||
std::vector<std::vector<std::string>> activations = {{"relu", "sigmoid", "tanh"}, {"sigmoid", "tanh", "tanh"},
|
||||
{"tanh", "relu", "sigmoid"}, {"sigmoid", "sigmoid", "sigmoid"},
|
||||
{"tanh", "tanh", "tanh"}, {"relu", "relu", "relu"}};
|
||||
std::vector<float> clip{0.f};
|
||||
std::vector<float> clip_non_zeros{0.7f};
|
||||
std::vector<ngraph::op::RecurrentSequenceDirection> direction = {ngraph::op::RecurrentSequenceDirection::FORWARD,
|
||||
ngraph::op::RecurrentSequenceDirection::REVERSE,
|
||||
ngraph::op::RecurrentSequenceDirection::BIDIRECTIONAL
|
||||
};
|
||||
std::vector<InferenceEngine::Precision> netPrecisions = {InferenceEngine::Precision::FP32,
|
||||
InferenceEngine::Precision::FP16};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(LSTMSequenceCommonZeroClip, LSTMSequenceTest,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(seq_lengths_zero_clip),
|
||||
::testing::ValuesIn(batch),
|
||||
::testing::ValuesIn(hidden_size),
|
||||
::testing::ValuesIn(input_size),
|
||||
::testing::ValuesIn(activations),
|
||||
::testing::ValuesIn(clip),
|
||||
::testing::ValuesIn(direction),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||
LSTMSequenceTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(LSTMSequenceCommonClip, LSTMSequenceTest,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(seq_lengths_clip_non_zero),
|
||||
::testing::ValuesIn(batch),
|
||||
::testing::ValuesIn(hidden_size),
|
||||
::testing::ValuesIn(input_size),
|
||||
::testing::ValuesIn(activations),
|
||||
::testing::ValuesIn(clip_non_zeros),
|
||||
::testing::ValuesIn(direction),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||
LSTMSequenceTest::getTestCaseName);
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright (C) 2019 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
#include <ngraph/op/util/attr_types.hpp>
|
||||
#include "single_layer_tests/rnn_sequence.hpp"
|
||||
#include "common_test_utils/test_constants.hpp"
|
||||
|
||||
using namespace LayerTestsDefinitions;
|
||||
|
||||
namespace {
|
||||
// without clip values increase rapidly, so use only seq_lenghts = 2
|
||||
std::vector<size_t> seq_lengths_zero_clip{2};
|
||||
std::vector<size_t> seq_lengths_clip_non_zero{20};
|
||||
std::vector<size_t> batch{1, 10};
|
||||
std::vector<size_t> hidden_size{1, 10};
|
||||
std::vector<size_t> input_size{10};
|
||||
std::vector<std::vector<std::string>> activations = {{"relu"}, {"sigmoid"}, {"tanh"}};
|
||||
std::vector<float> clip{0.f};
|
||||
std::vector<float> clip_non_zeros{0.7f};
|
||||
std::vector<ngraph::op::RecurrentSequenceDirection> direction = {ngraph::op::RecurrentSequenceDirection::FORWARD,
|
||||
ngraph::op::RecurrentSequenceDirection::REVERSE,
|
||||
ngraph::op::RecurrentSequenceDirection::BIDIRECTIONAL
|
||||
};
|
||||
std::vector<InferenceEngine::Precision> netPrecisions = {InferenceEngine::Precision::FP32,
|
||||
InferenceEngine::Precision::FP16};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(RNNSequenceCommonZeroClip, RNNSequenceTest,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(seq_lengths_zero_clip),
|
||||
::testing::ValuesIn(batch),
|
||||
::testing::ValuesIn(hidden_size),
|
||||
::testing::ValuesIn(input_size),
|
||||
::testing::ValuesIn(activations),
|
||||
::testing::ValuesIn(clip),
|
||||
::testing::ValuesIn(direction),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||
RNNSequenceTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(RNNSequenceCommonClip, RNNSequenceTest,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(seq_lengths_clip_non_zero),
|
||||
::testing::ValuesIn(batch),
|
||||
::testing::ValuesIn(hidden_size),
|
||||
::testing::ValuesIn(input_size),
|
||||
::testing::ValuesIn(activations),
|
||||
::testing::ValuesIn(clip_non_zeros),
|
||||
::testing::ValuesIn(direction),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||
RNNSequenceTest::getTestCaseName);
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright (C) 2019 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <ngraph/op/util/attr_types.hpp>
|
||||
#include "functional_test_utils/layer_test_utils.hpp"
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
#include "ngraph_functions/utils/ngraph_helpers.hpp"
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
using GRUSequenceParams = typename std::tuple<
|
||||
// bool, // using decompose to sub-ops transformation
|
||||
size_t, // seq_lengths
|
||||
size_t, // batch
|
||||
size_t, // hidden size
|
||||
size_t, // input size
|
||||
std::vector<std::string>, // activations
|
||||
float, // clip
|
||||
bool, // linear_before_reset
|
||||
ngraph::op::RecurrentSequenceDirection, // direction
|
||||
InferenceEngine::Precision, // Network precision
|
||||
std::string>; // Device name
|
||||
|
||||
class GRUSequenceTest : public testing::WithParamInterface<GRUSequenceParams>,
|
||||
virtual public LayerTestsUtils::LayerTestsCommon {
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<GRUSequenceParams> &obj);
|
||||
|
||||
protected:
|
||||
void SetUp() override;
|
||||
};
|
||||
|
||||
} // namespace LayerTestsDefinitions
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (C) 2019 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <ngraph/op/util/attr_types.hpp>
|
||||
#include "functional_test_utils/layer_test_utils.hpp"
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
#include "ngraph_functions/utils/ngraph_helpers.hpp"
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
using LSTMSequenceParams = typename std::tuple<
|
||||
// bool, // using decompose to sub-ops transformation
|
||||
size_t, // seq_lengths
|
||||
size_t, // batch
|
||||
size_t, // hidden size
|
||||
size_t, // input size
|
||||
std::vector<std::string>, // activations
|
||||
float, // clip
|
||||
ngraph::op::RecurrentSequenceDirection, // direction
|
||||
InferenceEngine::Precision, // Network precision
|
||||
std::string>; // Device name
|
||||
|
||||
class LSTMSequenceTest : public testing::WithParamInterface<LSTMSequenceParams>,
|
||||
virtual public LayerTestsUtils::LayerTestsCommon {
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<LSTMSequenceParams> &obj);
|
||||
|
||||
protected:
|
||||
void SetUp() override;
|
||||
};
|
||||
|
||||
} // namespace LayerTestsDefinitions
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (C) 2019 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <ngraph/op/util/attr_types.hpp>
|
||||
#include "functional_test_utils/layer_test_utils.hpp"
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
#include "ngraph_functions/utils/ngraph_helpers.hpp"
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
using RNNSequenceParams = typename std::tuple<
|
||||
// bool, // using decompose to sub-ops transformation
|
||||
size_t, // seq_lengths
|
||||
size_t, // batch
|
||||
size_t, // hidden size
|
||||
size_t, // input size
|
||||
std::vector<std::string>, // activations
|
||||
float, // clip
|
||||
ngraph::op::RecurrentSequenceDirection, // direction
|
||||
InferenceEngine::Precision, // Network precision
|
||||
std::string>; // Device name
|
||||
|
||||
class RNNSequenceTest : public testing::WithParamInterface<RNNSequenceParams>,
|
||||
virtual public LayerTestsUtils::LayerTestsCommon {
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<RNNSequenceParams> &obj);
|
||||
|
||||
protected:
|
||||
void SetUp() override;
|
||||
};
|
||||
|
||||
} // namespace LayerTestsDefinitions
|
||||
@@ -72,7 +72,8 @@ void GRUCellTest::SetUp() {
|
||||
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
|
||||
auto params = ngraph::builder::makeParams(ngPrc, {inputShapes[0], inputShapes[1]});
|
||||
std::vector<ngraph::Shape> WRB = {inputShapes[2], inputShapes[3], inputShapes[4]};
|
||||
auto gru_cell = ngraph::builder::makeGRUCell(ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes(params)),
|
||||
auto gru_cell = ngraph::builder::makeGRU(
|
||||
ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes(params)),
|
||||
WRB, hidden_size, activations, {}, {}, clip, linear_before_reset);
|
||||
ngraph::ResultVector results{std::make_shared<ngraph::opset1::Result>(gru_cell->output(0))};
|
||||
function = std::make_shared<ngraph::Function>(results, params, "gru_cell");
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
// Copyright (C) 2019 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
#include "ie_core.hpp"
|
||||
|
||||
#include "common_test_utils/common_utils.hpp"
|
||||
#include "functional_test_utils/blob_utils.hpp"
|
||||
#include "functional_test_utils/precision_utils.hpp"
|
||||
#include "functional_test_utils/plugin_cache.hpp"
|
||||
#include "functional_test_utils/skip_tests_config.hpp"
|
||||
|
||||
#include "single_layer_tests/gru_sequence.hpp"
|
||||
#include <transformations/bidirectional_sequences_decomposition.hpp>
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
std::string GRUSequenceTest::getTestCaseName(const testing::TestParamInfo<GRUSequenceParams> &obj) {
|
||||
//bool should_decompose;
|
||||
size_t seq_lenghts;
|
||||
size_t batch;
|
||||
size_t hidden_size;
|
||||
size_t input_size;
|
||||
std::vector<std::string> activations;
|
||||
std::vector<float> activations_alpha;
|
||||
std::vector<float> activations_beta;
|
||||
float clip;
|
||||
bool linear_before_reset;
|
||||
ngraph::op::RecurrentSequenceDirection direction;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::string targetDevice;
|
||||
std::tie(seq_lenghts, batch, hidden_size, input_size, activations, clip, linear_before_reset, direction, netPrecision,
|
||||
targetDevice) = obj.param;
|
||||
std::vector<std::vector<size_t>> inputShapes = {
|
||||
{{batch, input_size}, {batch, hidden_size}, {batch, hidden_size}, {3 * hidden_size, input_size},
|
||||
{3 * hidden_size, hidden_size}, {(linear_before_reset ? 4 : 3) * hidden_size}},
|
||||
};
|
||||
std::ostringstream result;
|
||||
result << "seq_lenghts" << seq_lenghts << "_";
|
||||
result << "batch=" << batch << "_";
|
||||
result << "hidden_size=" << hidden_size << "_";
|
||||
result << "input_size=" << input_size << "_";
|
||||
result << "IS=" << CommonTestUtils::vec2str(inputShapes) << "_";
|
||||
result << "activations=" << CommonTestUtils::vec2str(activations) << "_";
|
||||
result << "direction=" << direction << "_";
|
||||
result << "clip=" << clip << "_";
|
||||
result << "netPRC=" << netPrecision.name() << "_";
|
||||
result << "targetDevice=" << targetDevice << "_";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void GRUSequenceTest::SetUp() {
|
||||
size_t seq_lenghts;
|
||||
// bool should_decompose;
|
||||
size_t batch;
|
||||
size_t hidden_size;
|
||||
size_t input_size;
|
||||
std::vector<std::string> activations;
|
||||
std::vector<float> activations_alpha;
|
||||
std::vector<float> activations_beta;
|
||||
float clip;
|
||||
bool linear_before_reset;
|
||||
ngraph::op::RecurrentSequenceDirection direction;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::tie(seq_lenghts, batch, hidden_size, input_size, activations, clip, linear_before_reset, direction, netPrecision,
|
||||
targetDevice) = this->GetParam();
|
||||
size_t num_directions = direction == ngraph::op::RecurrentSequenceDirection::BIDIRECTIONAL ? 2 : 1;
|
||||
std::vector<std::vector<size_t>> inputShapes = {
|
||||
{{batch, seq_lenghts, input_size}, {batch, num_directions, hidden_size}, {batch},
|
||||
{num_directions, 3 * hidden_size, input_size}, {num_directions, 3 * hidden_size, hidden_size},
|
||||
{num_directions, (linear_before_reset ? 4 : 3) * hidden_size}},
|
||||
};
|
||||
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
|
||||
auto params = ngraph::builder::makeParams(ngPrc, {inputShapes[0], inputShapes[1]});
|
||||
std::vector<ngraph::Shape> WRB = {inputShapes[3], inputShapes[4], inputShapes[5], inputShapes[2]};
|
||||
auto gru_sequence = ngraph::builder::makeGRU(ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes(params)),
|
||||
WRB, hidden_size, activations, {}, {}, clip, linear_before_reset, true, direction);
|
||||
ngraph::ResultVector results{std::make_shared<ngraph::opset1::Result>(gru_sequence->output(0)),
|
||||
std::make_shared<ngraph::opset1::Result>(gru_sequence->output(1))};
|
||||
function = std::make_shared<ngraph::Function>(results, params, "gru_sequence");
|
||||
if (direction == ngraph::op::RecurrentSequenceDirection::BIDIRECTIONAL) {
|
||||
ngraph::pass::Manager m;
|
||||
m.register_pass<ngraph::pass::BidirectionalGRUSequenceDecomposition>();
|
||||
m.run_passes(function);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_P(GRUSequenceTest, CompareWithRefs) {
|
||||
Run();
|
||||
};
|
||||
} // namespace LayerTestsDefinitions
|
||||
@@ -70,7 +70,7 @@ void LSTMCellTest::SetUp() {
|
||||
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
|
||||
auto params = ngraph::builder::makeParams(ngPrc, {inputShapes[0], inputShapes[1], inputShapes[2]});
|
||||
std::vector<ngraph::Shape> WRB = {inputShapes[3], inputShapes[4], inputShapes[5]};
|
||||
auto lstm_cell = ngraph::builder::makeLSTMCell(ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes(params)),
|
||||
auto lstm_cell = ngraph::builder::makeLSTM(ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes(params)),
|
||||
WRB, hidden_size, activations, {}, {}, clip);
|
||||
ngraph::ResultVector results{std::make_shared<ngraph::opset1::Result>(lstm_cell->output(0)),
|
||||
std::make_shared<ngraph::opset1::Result>(lstm_cell->output(1))};
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
// Copyright (C) 2019 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
#include "ie_core.hpp"
|
||||
|
||||
#include "common_test_utils/common_utils.hpp"
|
||||
#include "functional_test_utils/blob_utils.hpp"
|
||||
#include "functional_test_utils/precision_utils.hpp"
|
||||
#include "functional_test_utils/plugin_cache.hpp"
|
||||
#include "functional_test_utils/skip_tests_config.hpp"
|
||||
|
||||
#include "single_layer_tests/lstm_sequence.hpp"
|
||||
#include <transformations/bidirectional_sequences_decomposition.hpp>
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
std::string LSTMSequenceTest::getTestCaseName(const testing::TestParamInfo<LSTMSequenceParams> &obj) {
|
||||
//bool should_decompose;
|
||||
size_t seq_lenghts;
|
||||
size_t batch;
|
||||
size_t hidden_size;
|
||||
size_t input_size;
|
||||
std::vector<std::string> activations;
|
||||
std::vector<float> activations_alpha;
|
||||
std::vector<float> activations_beta;
|
||||
float clip;
|
||||
ngraph::op::RecurrentSequenceDirection direction;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::string targetDevice;
|
||||
std::tie(seq_lenghts, batch, hidden_size, input_size, activations, clip, direction, netPrecision,
|
||||
targetDevice) = obj.param;
|
||||
std::vector<std::vector<size_t>> inputShapes = {
|
||||
{{batch, input_size}, {batch, hidden_size}, {batch, hidden_size}, {4 * hidden_size, input_size},
|
||||
{4 * hidden_size, hidden_size}, {4 * hidden_size}},
|
||||
};
|
||||
std::ostringstream result;
|
||||
result << "seq_lenghts" << seq_lenghts << "_";
|
||||
result << "batch=" << batch << "_";
|
||||
result << "hidden_size=" << hidden_size << "_";
|
||||
result << "input_size=" << input_size << "_";
|
||||
result << "IS=" << CommonTestUtils::vec2str(inputShapes) << "_";
|
||||
result << "activations=" << CommonTestUtils::vec2str(activations) << "_";
|
||||
result << "direction=" << direction << "_";
|
||||
result << "clip=" << clip << "_";
|
||||
result << "netPRC=" << netPrecision.name() << "_";
|
||||
result << "targetDevice=" << targetDevice << "_";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void LSTMSequenceTest::SetUp() {
|
||||
size_t seq_lenghts;
|
||||
// bool should_decompose;
|
||||
size_t batch;
|
||||
size_t hidden_size;
|
||||
size_t input_size;
|
||||
std::vector<std::string> activations;
|
||||
std::vector<float> activations_alpha;
|
||||
std::vector<float> activations_beta;
|
||||
float clip;
|
||||
ngraph::op::RecurrentSequenceDirection direction;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::tie(seq_lenghts, batch, hidden_size, input_size, activations, clip, direction, netPrecision,
|
||||
targetDevice) = this->GetParam();
|
||||
size_t num_directions = direction == ngraph::op::RecurrentSequenceDirection::BIDIRECTIONAL ? 2 : 1;
|
||||
std::vector<std::vector<size_t>> inputShapes = {
|
||||
{{batch, seq_lenghts, input_size}, {batch, num_directions, hidden_size}, {batch, num_directions, hidden_size},
|
||||
{batch}, {num_directions, 4 * hidden_size, input_size}, {num_directions, 4 * hidden_size, hidden_size}, {num_directions, 4 * hidden_size}},
|
||||
};
|
||||
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
|
||||
auto params = ngraph::builder::makeParams(ngPrc, {inputShapes[0], inputShapes[1], inputShapes[2]});
|
||||
std::vector<ngraph::Shape> WRB = {inputShapes[4], inputShapes[5], inputShapes[6], inputShapes[3]};
|
||||
auto lstm_sequence = ngraph::builder::makeLSTM(ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes(params)),
|
||||
WRB, hidden_size, activations, {}, {}, clip, true, direction);
|
||||
ngraph::ResultVector results{std::make_shared<ngraph::opset1::Result>(lstm_sequence->output(0)),
|
||||
std::make_shared<ngraph::opset1::Result>(lstm_sequence->output(1)),
|
||||
std::make_shared<ngraph::opset1::Result>(lstm_sequence->output(2))};
|
||||
function = std::make_shared<ngraph::Function>(results, params, "lstm_sequence");
|
||||
if (direction == ngraph::op::RecurrentSequenceDirection::BIDIRECTIONAL) {
|
||||
ngraph::pass::Manager m;
|
||||
m.register_pass<ngraph::pass::BidirectionalLSTMSequenceDecomposition>();
|
||||
m.run_passes(function);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_P(LSTMSequenceTest, CompareWithRefs) {
|
||||
Run();
|
||||
};
|
||||
} // namespace LayerTestsDefinitions
|
||||
@@ -64,7 +64,8 @@ void RNNCellTest::SetUp() {
|
||||
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
|
||||
auto params = ngraph::builder::makeParams(ngPrc, {inputShapes[0], inputShapes[1]});
|
||||
std::vector<ngraph::Shape> WRB = {inputShapes[2], inputShapes[3], inputShapes[4]};
|
||||
auto rnn_cell = ngraph::builder::makeRNNCell(ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes(params)),
|
||||
auto rnn_cell = ngraph::builder::makeRNN(
|
||||
ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes(params)),
|
||||
WRB, hidden_size, activations, {}, {}, clip);
|
||||
ngraph::ResultVector results{std::make_shared<ngraph::opset1::Result>(rnn_cell)};
|
||||
function = std::make_shared<ngraph::Function>(results, params, "rnn_cell");
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
// Copyright (C) 2019 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
#include "ie_core.hpp"
|
||||
|
||||
#include "common_test_utils/common_utils.hpp"
|
||||
#include "functional_test_utils/blob_utils.hpp"
|
||||
#include "functional_test_utils/precision_utils.hpp"
|
||||
#include "functional_test_utils/plugin_cache.hpp"
|
||||
#include "functional_test_utils/skip_tests_config.hpp"
|
||||
|
||||
#include "single_layer_tests/rnn_sequence.hpp"
|
||||
#include <transformations/bidirectional_sequences_decomposition.hpp>
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
std::string RNNSequenceTest::getTestCaseName(const testing::TestParamInfo<RNNSequenceParams> &obj) {
|
||||
//bool should_decompose;
|
||||
size_t seq_lenghts;
|
||||
size_t batch;
|
||||
size_t hidden_size;
|
||||
size_t input_size;
|
||||
std::vector<std::string> activations;
|
||||
std::vector<float> activations_alpha;
|
||||
std::vector<float> activations_beta;
|
||||
float clip;
|
||||
ngraph::op::RecurrentSequenceDirection direction;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::string targetDevice;
|
||||
std::tie(seq_lenghts, batch, hidden_size, input_size, activations, clip, direction, netPrecision,
|
||||
targetDevice) = obj.param;
|
||||
std::vector<std::vector<size_t>> inputShapes = {
|
||||
{{batch, input_size}, {batch, hidden_size}, {batch, hidden_size}, {hidden_size, input_size},
|
||||
{hidden_size, hidden_size}, {hidden_size}},
|
||||
};
|
||||
std::ostringstream result;
|
||||
result << "seq_lenghts" << seq_lenghts << "_";
|
||||
result << "batch=" << batch << "_";
|
||||
result << "hidden_size=" << hidden_size << "_";
|
||||
result << "input_size=" << input_size << "_";
|
||||
result << "IS=" << CommonTestUtils::vec2str(inputShapes) << "_";
|
||||
result << "activations=" << CommonTestUtils::vec2str(activations) << "_";
|
||||
result << "direction=" << direction << "_";
|
||||
result << "clip=" << clip << "_";
|
||||
result << "netPRC=" << netPrecision.name() << "_";
|
||||
result << "targetDevice=" << targetDevice << "_";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void RNNSequenceTest::SetUp() {
|
||||
size_t seq_lenghts;
|
||||
// bool should_decompose;
|
||||
size_t batch;
|
||||
size_t hidden_size;
|
||||
size_t input_size;
|
||||
std::vector<std::string> activations;
|
||||
std::vector<float> activations_alpha;
|
||||
std::vector<float> activations_beta;
|
||||
float clip;
|
||||
ngraph::op::RecurrentSequenceDirection direction;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::tie(seq_lenghts, batch, hidden_size, input_size, activations, clip, direction, netPrecision,
|
||||
targetDevice) = this->GetParam();
|
||||
size_t num_directions = direction == ngraph::op::RecurrentSequenceDirection::BIDIRECTIONAL ? 2 : 1;
|
||||
std::vector<std::vector<size_t>> inputShapes = {
|
||||
{{batch, seq_lenghts, input_size}, {batch, num_directions, hidden_size}, {batch},
|
||||
{num_directions, hidden_size, input_size}, {num_directions, hidden_size, hidden_size},
|
||||
{num_directions, hidden_size}},
|
||||
};
|
||||
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
|
||||
auto params = ngraph::builder::makeParams(ngPrc, {inputShapes[0], inputShapes[1]});
|
||||
std::vector<ngraph::Shape> WRB = {inputShapes[3], inputShapes[4], inputShapes[5], inputShapes[2]};
|
||||
auto rnn_sequence = ngraph::builder::makeRNN(ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes(params)),
|
||||
WRB, hidden_size, activations, {}, {}, clip, true, direction);
|
||||
ngraph::ResultVector results{std::make_shared<ngraph::opset1::Result>(rnn_sequence->output(0)),
|
||||
std::make_shared<ngraph::opset1::Result>(rnn_sequence->output(1))};
|
||||
function = std::make_shared<ngraph::Function>(results, params, "rnn_sequence");
|
||||
if (direction == ngraph::op::RecurrentSequenceDirection::BIDIRECTIONAL) {
|
||||
ngraph::pass::Manager m;
|
||||
m.register_pass<ngraph::pass::BidirectionalRNNSequenceDecomposition>();
|
||||
m.run_passes(function);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_P(RNNSequenceTest, CompareWithRefs) {
|
||||
Run();
|
||||
};
|
||||
} // namespace LayerTestsDefinitions
|
||||
@@ -390,35 +390,40 @@ std::shared_ptr<ngraph::Node> makePad(const ngraph::Output<Node>& data,
|
||||
std::shared_ptr<ngraph::Node> makeBatchNormInference(const ngraph::Output<Node>& data,
|
||||
double epsilon);
|
||||
|
||||
std::shared_ptr<ngraph::Node> makeLSTMCell(const OutputVector& in,
|
||||
const std::vector<ngraph::Shape>& WRB,
|
||||
std::shared_ptr<ngraph::Node> makeLSTM(const OutputVector& in,
|
||||
const std::vector<ngraph::Shape>& constants,
|
||||
std::size_t hidden_size,
|
||||
const std::vector<std::string>& activations =
|
||||
std::vector<std::string>{"sigmoid", "tanh", "tanh"},
|
||||
const std::vector<float>& activations_alpha = {},
|
||||
const std::vector<float>& activations_beta = {},
|
||||
float clip = 0.f);
|
||||
float clip = 0.f,
|
||||
bool make_sequence = false,
|
||||
ngraph::op::RecurrentSequenceDirection direction = ngraph::op::RecurrentSequenceDirection::FORWARD);
|
||||
|
||||
std::shared_ptr<ngraph::Node> makeGRUCell(const OutputVector& in,
|
||||
const std::vector<ngraph::Shape>& WRB,
|
||||
std::size_t hidden_size,
|
||||
const std::vector<std::string>& activations =
|
||||
std::vector<std::string>{"sigmoid", "tanh"},
|
||||
const std::vector<float>& activations_alpha = {},
|
||||
const std::vector<float>& activations_beta = {},
|
||||
float clip = 0.f,
|
||||
bool linear_before_reset = false);
|
||||
std::shared_ptr<ngraph::Node> makeGRU(const OutputVector& in,
|
||||
const std::vector<ngraph::Shape>& constants,
|
||||
std::size_t hidden_size,
|
||||
const std::vector<std::string>& activations =
|
||||
std::vector<std::string>{"sigmoid", "tanh"},
|
||||
const std::vector<float>& activations_alpha = {},
|
||||
const std::vector<float>& activations_beta = {},
|
||||
float clip = 0.f,
|
||||
bool linear_before_reset = false,
|
||||
bool make_sequence = false,
|
||||
ngraph::op::RecurrentSequenceDirection direction = ngraph::op::RecurrentSequenceDirection::FORWARD);
|
||||
|
||||
std::shared_ptr<ngraph::Node> makeRNNCell(const OutputVector& in,
|
||||
const std::vector<ngraph::Shape>& WRB,
|
||||
std::size_t hidden_size,
|
||||
const std::vector<std::string>& activations = std::vector<std::string>{"tanh"},
|
||||
const std::vector<float>& activations_alpha = {},
|
||||
const std::vector<float>& activations_beta = {},
|
||||
float clip = 0.f);
|
||||
std::shared_ptr<ngraph::Node> makeRNN(const OutputVector& in,
|
||||
const std::vector<ngraph::Shape>& constants,
|
||||
std::size_t hidden_size,
|
||||
const std::vector<std::string>& activations = std::vector<std::string>{"tanh"},
|
||||
const std::vector<float>& activations_alpha = {},
|
||||
const std::vector<float>& activations_beta = {},
|
||||
float clip = 0.f,
|
||||
bool make_sequence = false,
|
||||
ngraph::op::RecurrentSequenceDirection direction = ngraph::op::RecurrentSequenceDirection::FORWARD);
|
||||
|
||||
std::shared_ptr<ngraph::Node> makeTile(const ngraph::Output<Node>& in,
|
||||
const std::vector<size_t>& repeats);
|
||||
|
||||
} // namespace builder
|
||||
} // namespace ngraph
|
||||
|
||||
@@ -10,21 +10,30 @@
|
||||
namespace ngraph {
|
||||
namespace builder {
|
||||
|
||||
std::shared_ptr<ngraph::Node> makeGRUCell(const OutputVector& in,
|
||||
const std::vector<ngraph::Shape>& WRB,
|
||||
std::size_t hidden_size,
|
||||
const std::vector<std::string>& activations,
|
||||
const std::vector<float>& activations_alpha,
|
||||
const std::vector<float>& activations_beta,
|
||||
float clip,
|
||||
bool linear_before_reset) {
|
||||
std::shared_ptr<ngraph::Node> makeGRU(const OutputVector& in,
|
||||
const std::vector<ngraph::Shape>& constants,
|
||||
std::size_t hidden_size,
|
||||
const std::vector<std::string>& activations,
|
||||
const std::vector<float>& activations_alpha,
|
||||
const std::vector<float>& activations_beta,
|
||||
float clip,
|
||||
bool linear_before_reset,
|
||||
bool make_sequence,
|
||||
ngraph::op::RecurrentSequenceDirection direction) {
|
||||
std::vector<float> empty;
|
||||
auto W = ngraph::builder::makeConstant(in[0].get_element_type(), WRB[0], empty, true);
|
||||
auto R = ngraph::builder::makeConstant(in[0].get_element_type(), WRB[1], empty, true);
|
||||
auto B = ngraph::builder::makeConstant(in[0].get_element_type(), WRB[2], empty, true);
|
||||
return std::make_shared<ngraph::opset4::GRUCell>(in[0], in[1], W, R, B, hidden_size, activations,
|
||||
activations_alpha, activations_beta, clip, linear_before_reset);
|
||||
auto W = ngraph::builder::makeConstant(in[0].get_element_type(), constants[0], empty, true);
|
||||
auto R = ngraph::builder::makeConstant(in[0].get_element_type(), constants[1], empty, true);
|
||||
auto B = ngraph::builder::makeConstant(in[0].get_element_type(), constants[2], empty, true);
|
||||
if (!make_sequence) {
|
||||
return std::make_shared<ngraph::opset4::GRUCell>(in[0], in[1], W, R, B, hidden_size, activations,
|
||||
activations_alpha, activations_beta, clip,
|
||||
linear_before_reset);
|
||||
} else {
|
||||
std::vector<float> lenghts(in[0].get_shape()[0], in[0].get_shape()[1]);
|
||||
auto seq_lenghts = ngraph::builder::makeConstant(in[0].get_element_type(), constants[3], lenghts, false);
|
||||
return std::make_shared<ngraph::op::v5::GRUSequence>(in[0], in[1], seq_lenghts, W, R, B, hidden_size, direction,
|
||||
activations, activations_alpha, activations_beta, clip, linear_before_reset);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace builder
|
||||
} // namespace ngraph
|
||||
@@ -10,20 +10,28 @@
|
||||
namespace ngraph {
|
||||
namespace builder {
|
||||
|
||||
std::shared_ptr<ngraph::Node> makeLSTMCell(const std::vector<ngraph::Output<Node>>& in,
|
||||
const std::vector<ngraph::Shape>& WRB,
|
||||
std::size_t hidden_size,
|
||||
const std::vector<std::string>& activations,
|
||||
const std::vector<float>& activations_alpha,
|
||||
const std::vector<float>& activations_beta,
|
||||
float clip) {
|
||||
std::shared_ptr<ngraph::Node> makeLSTM(const std::vector<ngraph::Output<Node>>& in,
|
||||
const std::vector<ngraph::Shape>& constants,
|
||||
std::size_t hidden_size,
|
||||
const std::vector<std::string>& activations,
|
||||
const std::vector<float>& activations_alpha,
|
||||
const std::vector<float>& activations_beta,
|
||||
float clip,
|
||||
bool make_sequence,
|
||||
ngraph::op::RecurrentSequenceDirection direction) {
|
||||
std::vector<float> empty;
|
||||
auto W = ngraph::builder::makeConstant(in[0].get_element_type(), WRB[0], empty, true);
|
||||
auto R = ngraph::builder::makeConstant(in[0].get_element_type(), WRB[1], empty, true);
|
||||
auto B = ngraph::builder::makeConstant(in[0].get_element_type(), WRB[2], empty, true);
|
||||
return std::make_shared<ngraph::opset4::LSTMCell>(in[0], in[1], in[2], W, R, B, hidden_size, activations,
|
||||
activations_alpha, activations_beta, clip);
|
||||
auto W = ngraph::builder::makeConstant(in[0].get_element_type(), constants[0], empty, true);
|
||||
auto R = ngraph::builder::makeConstant(in[0].get_element_type(), constants[1], empty, true);
|
||||
auto B = ngraph::builder::makeConstant(in[0].get_element_type(), constants[2], empty, true);
|
||||
if (!make_sequence) {
|
||||
return std::make_shared<ngraph::opset4::LSTMCell>(in[0], in[1], in[2], W, R, B, hidden_size, activations,
|
||||
activations_alpha, activations_beta, clip);
|
||||
} else {
|
||||
std::vector<float> lenghts(in[0].get_shape()[0], in[0].get_shape()[1]);
|
||||
auto seq_lenghts = ngraph::builder::makeConstant(in[0].get_element_type(), constants[3], lenghts, false);
|
||||
return std::make_shared<ngraph::op::v5::LSTMSequence>(in[0], in[1], in[2], seq_lenghts, W, R, B, hidden_size, direction,
|
||||
activations_alpha, activations_beta, activations, clip);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace builder
|
||||
} // namespace ngraph
|
||||
@@ -10,20 +10,28 @@
|
||||
namespace ngraph {
|
||||
namespace builder {
|
||||
|
||||
std::shared_ptr<ngraph::Node> makeRNNCell(const OutputVector& in,
|
||||
const std::vector<ngraph::Shape>& WRB,
|
||||
std::size_t hidden_size,
|
||||
const std::vector<std::string>& activations,
|
||||
const std::vector<float>& activations_alpha,
|
||||
const std::vector<float>& activations_beta,
|
||||
float clip) {
|
||||
std::shared_ptr<ngraph::Node> makeRNN(const OutputVector& in,
|
||||
const std::vector<ngraph::Shape>& constants,
|
||||
std::size_t hidden_size,
|
||||
const std::vector<std::string>& activations,
|
||||
const std::vector<float>& activations_alpha,
|
||||
const std::vector<float>& activations_beta,
|
||||
float clip,
|
||||
bool make_sequence,
|
||||
ngraph::op::RecurrentSequenceDirection direction) {
|
||||
std::vector<float> empty;
|
||||
auto W = ngraph::builder::makeConstant(in[0].get_element_type(), WRB[0], empty, true);
|
||||
auto R = ngraph::builder::makeConstant(in[0].get_element_type(), WRB[1], empty, true);
|
||||
auto B = ngraph::builder::makeConstant(in[0].get_element_type(), WRB[2], empty, true);
|
||||
return std::make_shared<ngraph::opset4::RNNCell>(in[0], in[1], W, R, B, hidden_size, activations,
|
||||
activations_alpha, activations_beta, clip);
|
||||
auto W = ngraph::builder::makeConstant(in[0].get_element_type(), constants[0], empty, true);
|
||||
auto R = ngraph::builder::makeConstant(in[0].get_element_type(), constants[1], empty, true);
|
||||
auto B = ngraph::builder::makeConstant(in[0].get_element_type(), constants[2], empty, true);
|
||||
if (!make_sequence) {
|
||||
return std::make_shared<ngraph::opset4::RNNCell>(in[0], in[1], W, R, B, hidden_size, activations,
|
||||
activations_alpha, activations_beta, clip);
|
||||
} else {
|
||||
std::vector<float> lenghts(in[0].get_shape()[0], in[0].get_shape()[1]);
|
||||
auto seq_lenghts = ngraph::builder::makeConstant(in[0].get_element_type(), constants[3], lenghts, false);
|
||||
return std::make_shared<ngraph::op::v5::RNNSequence>(in[0], in[1], seq_lenghts, W, R, B, hidden_size, direction,
|
||||
activations, activations_alpha, activations_beta, clip);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace builder
|
||||
} // namespace ngraph
|
||||
Reference in New Issue
Block a user