LSTMCell/Sequence v1, reference implementations and decompose transformations for LSTM/GRU/RNN Cells (#2000)
* 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 * 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 Co-authored-by: Szymon Durawa <szymon.durawa@intel.com>
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
// Copyright (C) 2019 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "functional_test_utils/layer_test_utils.hpp"
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
#include "ngraph_functions/utils/ngraph_helpers.hpp"
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
using GRUCellParams = typename std::tuple<
|
||||
bool, // using decompose to sub-ops transformation
|
||||
size_t, // batch
|
||||
size_t, // hidden size
|
||||
size_t, // input size
|
||||
std::vector<std::string>, // activations
|
||||
float, // clip
|
||||
bool, // linear_before_reset
|
||||
InferenceEngine::Precision, // Network precision
|
||||
std::string>; // Device name
|
||||
|
||||
class GRUCellTest : public testing::WithParamInterface<GRUCellParams >,
|
||||
virtual public LayerTestsUtils::LayerTestsCommon {
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<GRUCellParams> &obj);
|
||||
|
||||
protected:
|
||||
void SetUp() override;
|
||||
};
|
||||
|
||||
} // namespace LayerTestsDefinitions
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2019 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "functional_test_utils/layer_test_utils.hpp"
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
#include "ngraph_functions/utils/ngraph_helpers.hpp"
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
using LSTMCellParams = typename std::tuple<
|
||||
bool, // using decompose to sub-ops transformation
|
||||
size_t, // batch
|
||||
size_t, // hidden size
|
||||
size_t, // input size
|
||||
std::vector<std::string>, // activations
|
||||
float, // clip
|
||||
InferenceEngine::Precision, // Network precision
|
||||
std::string>; // Device name
|
||||
|
||||
class LSTMCellTest : public testing::WithParamInterface<LSTMCellParams >,
|
||||
virtual public LayerTestsUtils::LayerTestsCommon {
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<LSTMCellParams> &obj);
|
||||
|
||||
protected:
|
||||
void SetUp() override;
|
||||
};
|
||||
|
||||
} // namespace LayerTestsDefinitions
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2019 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "functional_test_utils/layer_test_utils.hpp"
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
#include "ngraph_functions/utils/ngraph_helpers.hpp"
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
using RNNCellParams = typename std::tuple<
|
||||
bool, // using decompose to sub-ops transformation
|
||||
size_t, // batch
|
||||
size_t, // hidden size
|
||||
size_t, // input size
|
||||
std::vector<std::string>, // activations
|
||||
float, // clip
|
||||
InferenceEngine::Precision, // Network precision
|
||||
std::string>; // Device name
|
||||
|
||||
class RNNCellTest : public testing::WithParamInterface<RNNCellParams >,
|
||||
virtual public LayerTestsUtils::LayerTestsCommon {
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<RNNCellParams> &obj);
|
||||
|
||||
protected:
|
||||
void SetUp() override;
|
||||
};
|
||||
|
||||
} // namespace LayerTestsDefinitions
|
||||
@@ -0,0 +1,90 @@
|
||||
// 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 <transformations/gru_cell_decomposition.hpp>
|
||||
#include "single_layer_tests/gru_cell.hpp"
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
std::string GRUCellTest::getTestCaseName(const testing::TestParamInfo<GRUCellParams> &obj) {
|
||||
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;
|
||||
std::vector<std::vector<size_t>> inputShapes;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::string targetDevice;
|
||||
std::tie(should_decompose, batch, hidden_size, input_size, activations, clip,
|
||||
linear_before_reset, netPrecision, targetDevice) = obj.param;
|
||||
std::ostringstream result;
|
||||
result << "decomposition" << should_decompose << "_";
|
||||
result << "batch=" << batch << "_";
|
||||
result << "hidden_size=" << hidden_size << "_";
|
||||
result << "input_size=" << input_size << "_";
|
||||
result << "IS=" << CommonTestUtils::vec2str(inputShapes) << "_";
|
||||
result << "activations=" << CommonTestUtils::vec2str(activations) << "_";
|
||||
result << "clip=" << clip << "_";
|
||||
result << "linear_before_reset=" << linear_before_reset << "_";
|
||||
result << "netPRC=" << netPrecision.name() << "_";
|
||||
result << "targetDevice=" << targetDevice << "_";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void GRUCellTest::SetUp() {
|
||||
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;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::tie(should_decompose, batch, hidden_size, input_size, activations, clip, linear_before_reset,
|
||||
netPrecision, targetDevice) = this->GetParam();
|
||||
|
||||
std::vector<std::vector<size_t>> inputShapes = {
|
||||
{{batch, input_size}, {batch, hidden_size}, {3 * hidden_size, input_size},
|
||||
{3 * hidden_size, hidden_size}, {(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[2], inputShapes[3], inputShapes[4]};
|
||||
auto gru_cell = ngraph::builder::makeGRUCell(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");
|
||||
if (should_decompose) {
|
||||
ngraph::pass::Manager m;
|
||||
m.register_pass<ngraph::pass::GRUCellDecomposition>();
|
||||
m.run_passes(function);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_P(GRUCellTest, CompareWithRefs) {
|
||||
Run();
|
||||
};
|
||||
} // namespace LayerTestsDefinitions
|
||||
@@ -0,0 +1,89 @@
|
||||
// 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 <transformations/lstm_cell_decomposition.hpp>
|
||||
#include "single_layer_tests/lstm_cell.hpp"
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
std::string LSTMCellTest::getTestCaseName(const testing::TestParamInfo<LSTMCellParams> &obj) {
|
||||
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;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::string targetDevice;
|
||||
std::tie(should_decompose, batch, hidden_size, input_size, activations, clip, 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 << "decomposition" << should_decompose << "_";
|
||||
result << "batch=" << batch << "_";
|
||||
result << "hidden_size=" << hidden_size << "_";
|
||||
result << "input_size=" << input_size << "_";
|
||||
result << "IS=" << CommonTestUtils::vec2str(inputShapes) << "_";
|
||||
result << "activations=" << CommonTestUtils::vec2str(activations) << "_";
|
||||
result << "clip=" << clip << "_";
|
||||
result << "netPRC=" << netPrecision.name() << "_";
|
||||
result << "targetDevice=" << targetDevice << "_";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void LSTMCellTest::SetUp() {
|
||||
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;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::tie(should_decompose, batch, hidden_size, input_size, activations, clip, netPrecision,
|
||||
targetDevice) = this->GetParam();
|
||||
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}},
|
||||
};
|
||||
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)),
|
||||
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))};
|
||||
function = std::make_shared<ngraph::Function>(results, params, "lstm_cell");
|
||||
if (should_decompose) {
|
||||
ngraph::pass::Manager m;
|
||||
m.register_pass<ngraph::pass::LSTMCellDecomposition>();
|
||||
m.run_passes(function);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_P(LSTMCellTest, CompareWithRefs) {
|
||||
Run();
|
||||
};
|
||||
} // namespace LayerTestsDefinitions
|
||||
@@ -0,0 +1,82 @@
|
||||
// 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 <transformations/rnn_cell_decomposition.hpp>
|
||||
#include "single_layer_tests/rnn_cell.hpp"
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
std::string RNNCellTest::getTestCaseName(const testing::TestParamInfo<RNNCellParams> &obj) {
|
||||
bool should_decompose;
|
||||
size_t batch;
|
||||
size_t hidden_size;
|
||||
size_t input_size;
|
||||
std::vector<std::string> activations;
|
||||
float clip;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::string targetDevice;
|
||||
std::tie(should_decompose, batch, hidden_size, input_size, activations, clip,
|
||||
netPrecision, targetDevice) = obj.param;
|
||||
std::vector<std::vector<size_t>> inputShapes = {{batch, input_size}, {batch, hidden_size},
|
||||
{hidden_size, input_size}, {hidden_size, hidden_size}, {hidden_size}};
|
||||
std::ostringstream result;
|
||||
result << "decomposition" << should_decompose << "_";
|
||||
result << "batch=" << batch << "_";
|
||||
result << "hidden_size=" << hidden_size << "_";
|
||||
result << "input_size=" << input_size << "_";
|
||||
result << "IS=" << CommonTestUtils::vec2str(inputShapes) << "_";
|
||||
result << "activations=" << CommonTestUtils::vec2str(activations) << "_";
|
||||
result << "clip=" << clip << "_";
|
||||
result << "netPRC=" << netPrecision.name() << "_";
|
||||
result << "targetDevice=" << targetDevice << "_";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void RNNCellTest::SetUp() {
|
||||
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;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::tie(should_decompose, batch, hidden_size, input_size, activations, clip,
|
||||
netPrecision, targetDevice) = this->GetParam();
|
||||
std::vector<std::vector<size_t>> inputShapes = {{batch, input_size}, {batch, hidden_size},
|
||||
{hidden_size, input_size}, {hidden_size, hidden_size}, {hidden_size}};
|
||||
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)),
|
||||
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");
|
||||
if (should_decompose) {
|
||||
ngraph::pass::Manager m;
|
||||
m.register_pass<ngraph::pass::RNNCellDecomposition>();
|
||||
m.run_passes(function);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_P(RNNCellTest, CompareWithRefs) {
|
||||
Run();
|
||||
};
|
||||
} // namespace LayerTestsDefinitions
|
||||
@@ -72,7 +72,7 @@ void Basic_LSTM_S::SetUp() {
|
||||
//lstm [1, 10], [1, 118], [1, 118] -> [1, 118], [1, 118]
|
||||
outFormShapes1 = { batch_size, reshape1_shape[2] };
|
||||
auto constantX = std::make_shared<ngraph::opset1::Constant>(ngraph::element::i64, ngraph::Shape{2}, outFormShapes1);
|
||||
auto lstm1 = std::make_shared<ngraph::opset1::LSTMCell>(std::make_shared<ngraph::opset1::Reshape>(X, constantX, false),
|
||||
auto lstm1 = std::make_shared<ngraph::opset4::LSTMCell>(std::make_shared<ngraph::opset1::Reshape>(X, constantX, false),
|
||||
H_t, C_t,
|
||||
weightsNode, reccurrenceWeightsNode, hidden_size);
|
||||
|
||||
@@ -137,7 +137,7 @@ std::shared_ptr<ngraph::Function> Basic_LSTM_S::CreateGraphWithUnrolledTI() {
|
||||
|
||||
ngraph::Output<ngraph::Node> H[iterations + 1];
|
||||
ngraph::Output<ngraph::Node> C[iterations + 1];
|
||||
std::shared_ptr<ngraph::opset1::LSTMCell> lstm[iterations];
|
||||
std::shared_ptr<ngraph::opset4::LSTMCell> lstm[iterations];
|
||||
H[0] = ngraph::builder::makeConstant<float>(ngPrc, { batch_size, hidden_size }, {}, true);
|
||||
C[0] = ngraph::builder::makeConstant<float>(ngPrc, { batch_size, hidden_size }, {}, true);
|
||||
auto reshape1_shape = reshape1->output(0).get_shape();
|
||||
@@ -149,7 +149,7 @@ std::shared_ptr<ngraph::Function> Basic_LSTM_S::CreateGraphWithUnrolledTI() {
|
||||
|
||||
for (size_t i = 0; i < iterations; ++i) {
|
||||
auto X = split1->output(i);
|
||||
lstm[i] = std::make_shared<ngraph::opset1::LSTMCell>(std::make_shared<ngraph::opset1::Reshape>(X, constantX, false),
|
||||
lstm[i] = std::make_shared<ngraph::opset4::LSTMCell>(std::make_shared<ngraph::opset1::Reshape>(X, constantX, false),
|
||||
H[i], C[i],
|
||||
weightsNode, reccurrenceWeightsNode, hidden_size);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user