[Core]lstm test api20 (#21031)

* [Core] lstm api fix

* Fix LSTMCell failure issues

* Solve GNA failures

* Update for comments

* Minor update

* Use new ov::test::utils::makeEltwise

---------

Co-authored-by: Durandin, Pavel <pavel.durandin@intel.com>
This commit is contained in:
River Li 2023-11-27 14:25:58 +08:00 committed by GitHub
parent 058001eb84
commit a6463c1ac6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 939 additions and 863 deletions

View File

@ -3,7 +3,6 @@
//
#include <vector>
#include "single_op_tests/memory.h"
namespace {
@ -24,11 +23,7 @@ const std::vector<ov::element::Type> input_types = {
ov::element::f32,
};
const std::vector<int64_t> iterationCount {
1,
3,
10
};
const std::vector<int64_t> iterationCount{1, 3, 10};
INSTANTIATE_TEST_SUITE_P(smoke_MemoryTest, MemoryLayerTest,
::testing::Combine(
@ -39,5 +34,5 @@ INSTANTIATE_TEST_SUITE_P(smoke_MemoryTest, MemoryLayerTest,
::testing::Values(ov::test::utils::DEVICE_CPU, "HETERO:CPU")),
MemoryLayerTest::getTestCaseName);
} // namespace
} // namespace

View File

@ -2,42 +2,38 @@
// SPDX-License-Identifier: Apache-2.0
//
#include <subgraph_tests/memory_LSTMCell.hpp>
#include "subgraph_tests/memory_LSTMCell.hpp"
#include "common_test_utils/test_constants.hpp"
namespace SubgraphTestsDefinitions {
std::vector<ngraph::helpers::MemoryTransformation> transformation {
ngraph::helpers::MemoryTransformation::NONE,
ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2,
ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2_REGULAR_API
};
namespace ov {
namespace test {
std::vector<size_t> input_sizes = {
80,
32,
64,
100,
25
};
std::vector<ov::test::utils::MemoryTransformation> transformation{
ov::test::utils::MemoryTransformation::NONE,
ov::test::utils::MemoryTransformation::LOW_LATENCY_V2,
};
std::vector<size_t> hidden_sizes = {
128,
200,
300,
24,
32,
};
std::vector<size_t> input_sizes = {80, 32, 64, 100, 25};
std::map<std::string, std::string> additional_config = {
};
std::vector<size_t> hidden_sizes = {
128,
200,
300,
24,
32,
};
INSTANTIATE_TEST_SUITE_P(smoke_MemoryLSTMCellTest, MemoryLSTMCellTest,
::testing::Combine(
::testing::ValuesIn(transformation),
::testing::Values(ov::test::utils::DEVICE_CPU),
::testing::Values(InferenceEngine::Precision::FP32),
::testing::ValuesIn(input_sizes),
::testing::ValuesIn(hidden_sizes),
::testing::Values(additional_config)),
MemoryLSTMCellTest::getTestCaseName);
} // namespace SubgraphTestsDefinitions
ov::AnyMap additional_config = {};
INSTANTIATE_TEST_SUITE_P(smoke_MemoryLSTMCellTest,
MemoryLSTMCellTest,
::testing::Combine(::testing::ValuesIn(transformation),
::testing::Values(ov::test::utils::DEVICE_CPU),
::testing::Values(ov::element::f32),
::testing::ValuesIn(input_sizes),
::testing::ValuesIn(hidden_sizes),
::testing::Values(additional_config)),
MemoryLSTMCellTest::getTestCaseName);
} // namespace test
} // namespace ov

View File

@ -2,24 +2,19 @@
// SPDX-License-Identifier: Apache-2.0
//
#include <subgraph_tests/multiple_LSTMCell.hpp>
#include "subgraph_tests/multiple_LSTMCell.hpp"
#include "common_test_utils/test_constants.hpp"
namespace SubgraphTestsDefinitions {
namespace ov {
namespace test {
namespace {
std::vector<ngraph::helpers::MemoryTransformation> transformation {
ngraph::helpers::MemoryTransformation::NONE,
ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2,
ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2_REGULAR_API
};
std::vector<ov::test::utils::MemoryTransformation> transformation{
ov::test::utils::MemoryTransformation::NONE,
ov::test::utils::MemoryTransformation::LOW_LATENCY_V2};
std::vector<size_t> input_sizes = {
80,
32,
64,
25
};
std::vector<size_t> input_sizes = {80, 32, 64, 25};
std::vector<size_t> hidden_sizes = {
64,
@ -28,18 +23,17 @@ std::vector<size_t> hidden_sizes = {
32,
};
std::map<std::string, std::string> additional_config = {
};
} // namespace
ov::AnyMap additional_config = {};
} // namespace
INSTANTIATE_TEST_SUITE_P(MultipleLSTMCellTest, MultipleLSTMCellTest,
::testing::Combine(
::testing::ValuesIn(transformation),
::testing::Values(ov::test::utils::DEVICE_CPU),
::testing::Values(InferenceEngine::Precision::FP32),
::testing::ValuesIn(input_sizes),
::testing::ValuesIn(hidden_sizes),
::testing::Values(additional_config)),
MultipleLSTMCellTest::getTestCaseName);
} // namespace SubgraphTestsDefinitions
INSTANTIATE_TEST_SUITE_P(MultipleLSTMCellTest,
MultipleLSTMCellTest,
::testing::Combine(::testing::ValuesIn(transformation),
::testing::Values(ov::test::utils::DEVICE_CPU),
::testing::Values(ov::element::f32),
::testing::ValuesIn(input_sizes),
::testing::ValuesIn(hidden_sizes),
::testing::Values(additional_config)),
MultipleLSTMCellTest::getTestCaseName);
} // namespace test
} // namespace ov

View File

@ -65,7 +65,6 @@ TEST_P(MemoryTestGna, CompareWithRefs) {
std::vector<ngraph::helpers::MemoryTransformation> transformation{
ngraph::helpers::MemoryTransformation::NONE,
ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2,
ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2_REGULAR_API,
ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2_ORIGINAL_INIT};
const std::vector<InferenceEngine::SizeVector> inShapes = {{1, 1}, {1, 2}, {1, 10}};

View File

@ -2,15 +2,14 @@
// SPDX-License-Identifier: Apache-2.0
//
#include <subgraph_tests/memory_LSTMCell.hpp>
#include "subgraph_tests/memory_LSTMCell.hpp"
#include "common_test_utils/test_constants.hpp"
namespace ov {
namespace test {
namespace SubgraphTestsDefinitions {
std::vector<ngraph::helpers::MemoryTransformation> transformation{
ngraph::helpers::MemoryTransformation::NONE,
ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2,
ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2_REGULAR_API};
std::vector<ov::test::utils::MemoryTransformation> transformation{
ov::test::utils::MemoryTransformation::NONE,
ov::test::utils::MemoryTransformation::LOW_LATENCY_V2};
std::vector<size_t> input_sizes = {80, 32, 64, 100, 25};
@ -22,7 +21,7 @@ std::vector<size_t> hidden_sizes = {
32,
};
std::map<std::string, std::string> additional_config = {
ov::AnyMap additional_config = {
{"GNA_COMPACT_MODE", "NO"},
{"GNA_DEVICE_MODE", "GNA_SW_EXACT"},
{"GNA_SCALE_FACTOR_0", "1638.4"},
@ -32,9 +31,10 @@ INSTANTIATE_TEST_SUITE_P(smoke_MemoryLSTMCellTest,
MemoryLSTMCellTest,
::testing::Combine(::testing::ValuesIn(transformation),
::testing::Values(ov::test::utils::DEVICE_GNA),
::testing::Values(InferenceEngine::Precision::FP32),
::testing::Values(ov::element::f32),
::testing::ValuesIn(input_sizes),
::testing::ValuesIn(hidden_sizes),
::testing::Values(additional_config)),
MemoryLSTMCellTest::getTestCaseName);
} // namespace SubgraphTestsDefinitions
} // namespace test
} // namespace ov

View File

@ -2,17 +2,17 @@
// SPDX-License-Identifier: Apache-2.0
//
#include <subgraph_tests/multiple_LSTMCell.hpp>
#include "subgraph_tests/multiple_LSTMCell.hpp"
#include "common_test_utils/test_constants.hpp"
namespace SubgraphTestsDefinitions {
namespace ov {
namespace test {
namespace {
std::vector<ngraph::helpers::MemoryTransformation> transformation{
ngraph::helpers::MemoryTransformation::NONE,
ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2,
ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2_REGULAR_API};
std::vector<ov::test::utils::MemoryTransformation> transformation{
ov::test::utils::MemoryTransformation::NONE,
ov::test::utils::MemoryTransformation::LOW_LATENCY_V2};
std::vector<size_t> input_sizes = {80, 32, 64, 25};
@ -23,7 +23,7 @@ std::vector<size_t> hidden_sizes = {
32,
};
std::map<std::string, std::string> additional_config = {
ov::AnyMap additional_config = {
{"GNA_COMPACT_MODE", "NO"},
{"GNA_DEVICE_MODE", "GNA_SW_EXACT"},
{"GNA_SCALE_FACTOR_0", "1638.4"},
@ -34,9 +34,10 @@ INSTANTIATE_TEST_SUITE_P(MultipleLSTMCellTest,
MultipleLSTMCellTest,
::testing::Combine(::testing::ValuesIn(transformation),
::testing::Values(ov::test::utils::DEVICE_GNA),
::testing::Values(InferenceEngine::Precision::FP32),
::testing::Values(ov::element::f32),
::testing::ValuesIn(input_sizes),
::testing::ValuesIn(hidden_sizes),
::testing::Values(additional_config)),
MultipleLSTMCellTest::getTestCaseName);
} // namespace SubgraphTestsDefinitions
} // namespace test
} // namespace ov

View File

@ -6,10 +6,12 @@
#include "shared_test_classes/subgraph/memory_LSTMCell.hpp"
namespace SubgraphTestsDefinitions {
namespace ov {
namespace test {
TEST_P(MemoryLSTMCellTest, CompareWithRefs) {
Run();
run();
};
} // namespace SubgraphTestsDefinitions
} // namespace test
} // namespace ov

View File

@ -6,10 +6,12 @@
#include "shared_test_classes/subgraph/multiple_LSTMCell.hpp"
namespace SubgraphTestsDefinitions {
namespace ov {
namespace test {
TEST_P(MultipleLSTMCellTest, CompareWithRefs) {
Run();
run();
};
} // namespace SubgraphTestsDefinitions
} // namespace test
} // namespace ov

View File

@ -5,30 +5,31 @@
#pragma once
#include "common_test_utils/test_common.hpp"
#include "shared_test_classes/base/layer_test_utils.hpp"
#include <ie_core.hpp>
#include "ov_models/utils/ov_helpers.hpp"
#include "shared_test_classes/base/ov_subgraph.hpp"
namespace SubgraphTestsDefinitions {
typedef std::tuple<
ngraph::helpers::MemoryTransformation, // Apply Memory transformation
std::string, // Target device name
InferenceEngine::Precision, // Network precision
size_t, // Input size
size_t, // Hidden size
std::map<std::string, std::string> // Configuration
> memoryLSTMCellParams;
namespace ov {
namespace test {
typedef std::tuple<ov::test::utils::MemoryTransformation, // Apply Memory transformation
std::string, // Target device name
ov::element::Type, // Input element type
size_t, // Input size
size_t, // Hidden size
ov::AnyMap // Configuration
>
memoryLSTMCellParams;
class MemoryLSTMCellTest : virtual public LayerTestsUtils::LayerTestsCommon,
public testing::WithParamInterface<memoryLSTMCellParams> {
class MemoryLSTMCellTest : virtual public ov::test::SubgraphBaseStaticTest,
public testing::WithParamInterface<memoryLSTMCellParams> {
private:
// you have to Unroll TI manually and remove memory untill ngraph supports it
// you have to Unroll TI manually and remove memory until supports it
// since we switching models we need to generate and save weights biases and inputs in SetUp
void switchToNgraphFriendlyModel();
void CreatePureTensorIteratorModel();
void InitMemory();
void ApplyLowLatency();
void switch_to_friendly_model();
void create_pure_tensor_iterator_model();
void init_memory();
void apply_low_latency();
ngraph::helpers::MemoryTransformation transformation;
ov::test::utils::MemoryTransformation transformation;
std::vector<float> input_bias;
std::vector<float> input_weights;
std::vector<float> hidden_memory_init;
@ -36,12 +37,17 @@ private:
std::vector<float> weights_vals;
std::vector<float> reccurrenceWeights_vals;
std::vector<float> bias_vals;
std::vector<ov::Shape> input_shapes;
protected:
void SetUp() override;
void Run() override;
void LoadNetwork() override;
void Infer() override;
void run() override;
void compile_model() override;
void infer() override;
public:
static std::string getTestCaseName(const testing::TestParamInfo<memoryLSTMCellParams> &obj);
static std::string getTestCaseName(const testing::TestParamInfo<memoryLSTMCellParams>& obj);
};
} // namespace SubgraphTestsDefinitions
} // namespace test
} // namespace ov

View File

@ -4,29 +4,30 @@
#pragma once
#include "common_test_utils/test_common.hpp"
#include "shared_test_classes/base/layer_test_utils.hpp"
#include <ie_core.hpp>
#include "common_test_utils/test_enums.hpp"
#include "shared_test_classes/base/ov_subgraph.hpp"
namespace SubgraphTestsDefinitions {
typedef std::tuple<
ngraph::helpers::MemoryTransformation, // Apply Memory transformation
std::string, // Target device name
InferenceEngine::Precision, // Network precision
size_t, // Input size
size_t, // Hidden size
std::map<std::string, std::string> // Configuration
> multipleLSTMCellParams;
namespace ov {
namespace test {
class MultipleLSTMCellTest : virtual public LayerTestsUtils::LayerTestsCommon,
public testing::WithParamInterface<multipleLSTMCellParams> {
typedef std::tuple<ov::test::utils::MemoryTransformation, // Apply Memory transformation
std::string, // Target device name
ov::element::Type, // Input precision
size_t, // Input size
size_t, // Hidden size
ov::AnyMap // Configuration
>
multipleLSTMCellParams;
class MultipleLSTMCellTest : virtual public ov::test::SubgraphBaseStaticTest,
public testing::WithParamInterface<multipleLSTMCellParams> {
private:
// you have to Unroll TI manually and remove memory untill ngraph supports it
// you have to Unroll TI manually and remove memory until supports it
// since we switching models we need to generate and save weights biases and inputs in SetUp
void switchToNgraphFriendlyModel();
void CreatePureTensorIteratorModel();
void InitMemory();
void ApplyLowLatency();
void switch_to_friendly_model();
void create_pure_tensor_iterator_model();
void init_memory();
void apply_low_latency();
size_t hiddenSize;
std::vector<float> input_bias;
@ -37,12 +38,18 @@ private:
std::vector<float> weights_2_vals;
std::vector<float> reccurrenceWeights_vals;
std::vector<float> bias_vals;
ngraph::helpers::MemoryTransformation transformation;
ov::test::utils::MemoryTransformation transformation;
std::vector<ov::Shape> input_shapes;
protected:
void SetUp() override;
void LoadNetwork() override;
void Run() override;
void compile_model() override;
void run() override;
void infer() override;
public:
static std::string getTestCaseName(const testing::TestParamInfo<multipleLSTMCellParams> &obj);
static std::string getTestCaseName(const testing::TestParamInfo<multipleLSTMCellParams>& obj);
};
} // namespace SubgraphTestsDefinitions
} // namespace test
} // namespace ov

View File

@ -2,213 +2,214 @@
// SPDX-License-Identifier: Apache-2.0
//
#include "shared_test_classes/single_layer/memory.hpp"
#include <signal.h>
#include <functional_test_utils/core_config.hpp>
#include <ie_transformations.hpp>
#include <transformations/control_flow/unroll_tensor_iterator.hpp>
#include <functional_test_utils/core_config.hpp>
#include "ngraph/opsets/opset7.hpp"
#include "ov_models/builders.hpp"
#include "ngraph/pass/low_latency.hpp"
#include "openvino/op/util/variable_context.hpp"
#include "shared_test_classes/single_layer/memory.hpp"
#include "ov_models/builders.hpp"
using namespace ngraph;
using namespace opset7;
namespace LayerTestsDefinitions {
std::string MemoryTest::getTestCaseName(const testing::TestParamInfo<MemoryTestParams> &obj) {
int64_t iteration_count;
InferenceEngine::Precision netPrecision;
InferenceEngine::SizeVector inputShape;
std::string targetDevice;
ngraph::helpers::MemoryTransformation transformation;
std::tie(transformation, iteration_count, inputShape, netPrecision, targetDevice) = obj.param;
std::string MemoryTest::getTestCaseName(const testing::TestParamInfo<MemoryTestParams>& obj) {
int64_t iteration_count;
InferenceEngine::Precision netPrecision;
InferenceEngine::SizeVector inputShape;
std::string targetDevice;
ngraph::helpers::MemoryTransformation transformation;
std::tie(transformation, iteration_count, inputShape, netPrecision, targetDevice) = obj.param;
std::ostringstream result;
result << "transformation=" << transformation << "_";
result << "iteration_count=" << iteration_count << "_";
result << "IS=" << ov::test::utils::vec2str(inputShape) << "_";
result << "netPRC=" << netPrecision.name() << "_";
result << "trgDev=" << targetDevice;
result << ")";
return result.str();
std::ostringstream result;
result << "transformation=" << transformation << "_";
result << "iteration_count=" << iteration_count << "_";
result << "IS=" << ov::test::utils::vec2str(inputShape) << "_";
result << "netPRC=" << netPrecision.name() << "_";
result << "trgDev=" << targetDevice;
result << ")";
return result.str();
}
void MemoryTest::SetUp() {
std::tie(transformation, iteration_count, inputShape, netPrecision, targetDevice) = this->GetParam();
ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
if (transformation == ngraph::helpers::MemoryTransformation::NONE) {
CreateCommonFunc();
} else {
CreateTIFunc();
ApplyLowLatency();
}
void MemoryTest::SetUp() {
std::tie(transformation, iteration_count, inputShape, netPrecision, targetDevice) = this->GetParam();
ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
auto hostTensor = std::make_shared<HostTensor>(ngPrc, inputShape);
auto variable_context = ov::op::util::VariableContext();
auto variable_value = std::make_shared<VariableValue>(hostTensor);
variable_context.set_variable_value(function->get_variable_by_id("v0"), variable_value);
eval_context["VariableContext"] = variable_context;
}
if (transformation == ngraph::helpers::MemoryTransformation::NONE) {
CreateCommonFunc();
void MemoryTest::Run() {
functionRefs = ngraph::clone_function(*function);
SKIP_IF_CURRENT_TEST_IS_DISABLED()
using namespace LayerTestsUtils;
auto crashHandler = [](int errCode) {
auto& s = ov::test::utils::OpSummary::getInstance();
s.saveReport();
std::cout << "Unexpected application crash!" << std::endl;
std::abort();
};
signal(SIGSEGV, crashHandler);
auto& s = ov::test::utils::OpSummary::getInstance();
s.setDeviceName(targetDevice);
if (ov::test::utils::current_test_is_disabled()) {
s.updateOPsStats(function, ov::test::utils::PassRate::Statuses::SKIPPED);
GTEST_SKIP() << "Disabled test due to configuration" << std::endl;
} else {
s.updateOPsStats(function, ov::test::utils::PassRate::Statuses::CRASHED);
}
try {
if (transformation != ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2_REGULAR_API) {
LoadNetwork();
} else {
CreateTIFunc();
ApplyLowLatency();
CoreConfiguration(this);
ConfigureNetwork();
executableNetwork = core->LoadNetwork(cnnNetwork, targetDevice, configuration);
}
inferRequest = executableNetwork.CreateInferRequest();
GenerateInputs();
for (int64_t i = 0; i < iteration_count; ++i) {
Infer();
Validate();
}
s.updateOPsStats(functionRefs, ov::test::utils::PassRate::Statuses::PASSED);
} catch (const std::runtime_error& re) {
s.updateOPsStats(functionRefs, ov::test::utils::PassRate::Statuses::FAILED);
GTEST_FATAL_FAILURE_(re.what());
} catch (const std::exception& ex) {
s.updateOPsStats(functionRefs, ov::test::utils::PassRate::Statuses::FAILED);
GTEST_FATAL_FAILURE_(ex.what());
} catch (...) {
s.updateOPsStats(functionRefs, ov::test::utils::PassRate::Statuses::FAILED);
GTEST_FATAL_FAILURE_("Unknown failure occurred.");
}
}
auto hostTensor = std::make_shared<HostTensor>(ngPrc, inputShape);
auto variable_context = ov::op::util::VariableContext();
auto variable_value = std::make_shared<VariableValue>(hostTensor);
variable_context.set_variable_value(function->get_variable_by_id("v0"), variable_value);
eval_context["VariableContext"] = variable_context;
void MemoryTest::Infer() {
ConfigureInferRequest();
inferRequest.Infer();
}
std::vector<std::pair<element::Type, std::vector<std::uint8_t>>> MemoryTest::CalculateRefs() {
using namespace ngraph;
function->validate_nodes_and_infer_types();
auto referenceInputs = std::vector<std::vector<uint8_t>>(inputs.size());
auto refInputsTypes = std::vector<element::Type>(inputs.size());
HostTensorVector inputTensors;
for (auto& input : inputs) {
const auto& dataSize = input->byteSize();
const auto& tensorDesc = input->getTensorDesc();
auto memory = InferenceEngine::as<InferenceEngine::MemoryBlob>(input);
IE_ASSERT(memory);
const auto lockedMemory = memory->wmap();
const auto buffer = lockedMemory.as<const std::uint8_t*>();
auto hostTensor =
std::make_shared<HostTensor>(FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(tensorDesc.getPrecision()),
tensorDesc.getDims());
hostTensor->write(buffer, dataSize);
inputTensors.push_back(hostTensor);
}
void MemoryTest::Run() {
functionRefs = ngraph::clone_function(*function);
SKIP_IF_CURRENT_TEST_IS_DISABLED()
using namespace LayerTestsUtils;
auto crashHandler = [](int errCode) {
auto &s = ov::test::utils::OpSummary::getInstance();
s.saveReport();
std::cout << "Unexpected application crash!" << std::endl;
std::abort();
};
signal(SIGSEGV, crashHandler);
// evaluate method is not implemented for TI op.
ngraph::pass::Manager manager;
manager.register_pass<ov::pass::UnrollTensorIterator>();
manager.run_passes(function);
auto &s = ov::test::utils::OpSummary::getInstance();
s.setDeviceName(targetDevice);
if (ov::test::utils::current_test_is_disabled()) {
s.updateOPsStats(function, ov::test::utils::PassRate::Statuses::SKIPPED);
GTEST_SKIP() << "Disabled test due to configuration" << std::endl;
} else {
s.updateOPsStats(function, ov::test::utils::PassRate::Statuses::CRASHED);
}
try {
if (transformation != ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2_REGULAR_API) {
LoadNetwork();
} else {
CoreConfiguration(this);
ConfigureNetwork();
executableNetwork = core->LoadNetwork(cnnNetwork, targetDevice, configuration);
}
inferRequest = executableNetwork.CreateInferRequest();
GenerateInputs();
for (int64_t i = 0; i < iteration_count; ++i) {
Infer();
Validate();
}
s.updateOPsStats(functionRefs, ov::test::utils::PassRate::Statuses::PASSED);
}
catch (const std::runtime_error &re) {
s.updateOPsStats(functionRefs, ov::test::utils::PassRate::Statuses::FAILED);
GTEST_FATAL_FAILURE_(re.what());
} catch (const std::exception &ex) {
s.updateOPsStats(functionRefs, ov::test::utils::PassRate::Statuses::FAILED);
GTEST_FATAL_FAILURE_(ex.what());
} catch (...) {
s.updateOPsStats(functionRefs, ov::test::utils::PassRate::Statuses::FAILED);
GTEST_FATAL_FAILURE_("Unknown failure occurred.");
}
const auto& outInfo = executableNetwork.GetOutputsInfo();
HostTensorVector outputTensors(outInfo.size());
for (auto& outTensor : outputTensors) {
outTensor = std::make_shared<HostTensor>();
}
OPENVINO_SUPPRESS_DEPRECATED_START
function->evaluate(outputTensors, inputTensors, eval_context);
OPENVINO_SUPPRESS_DEPRECATED_END
void MemoryTest::Infer() {
ConfigureInferRequest();
inferRequest.Infer();
std::vector<std::pair<element::Type, std::vector<std::uint8_t>>> outputs(outInfo.size());
for (size_t idx = 0; idx < outInfo.size(); ++idx) {
outputs[idx].first = outputTensors[idx]->get_element_type();
outputs[idx].second.resize(outputTensors[idx]->get_size_in_bytes());
outputTensors[idx]->read(outputs[idx].second.data(), outputTensors[idx]->get_size_in_bytes());
}
return outputs;
}
std::vector<std::pair<element::Type, std::vector<std::uint8_t>>> MemoryTest::CalculateRefs() {
using namespace ngraph;
void MemoryTest::CreateTIFunc() {
auto param = std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape(inputShape));
std::vector<std::vector<size_t>> shape = {{static_cast<size_t>(iteration_count), 1}};
auto iter_count =
std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape{static_cast<size_t>(iteration_count), 1});
// Body
auto X = std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape(inputShape));
auto Y = std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape(inputShape));
auto Iter = std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape{1, 1});
auto add = std::make_shared<Add>(X, Y);
auto res = std::make_shared<Result>(add);
auto Iter_res = std::make_shared<Result>(Iter);
auto body = std::make_shared<Function>(OutputVector{res, Iter_res}, ParameterVector{X, Y, Iter});
// TI construction
auto tensor_iterator = std::make_shared<TensorIterator>();
tensor_iterator->set_body(body);
tensor_iterator->set_merged_input(X, param, res);
tensor_iterator->set_invariant_input(Y, param);
tensor_iterator->set_sliced_input(Iter, iter_count, 0, 1, 1, -1, 0);
auto output = tensor_iterator->get_iter_value(res, -1);
auto output_iter = tensor_iterator->get_concatenated_slices(Iter_res, 0, 1, 1, -1, 0);
function =
std::make_shared<Function>(OutputVector{output, output_iter}, ParameterVector{param, iter_count}, "PureTI");
}
void MemoryTest::CreateCommonFunc() {
ov::ParameterVector param{std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape(inputShape))};
const auto variable_info = targetDevice == ov::test::utils::DEVICE_GPU
? VariableInfo{Shape{inputShape}, ngPrc, "v0"}
: VariableInfo{inputShape, ngPrc, "v0"};
auto variable = std::make_shared<Variable>(variable_info);
auto read_value = CreateReadValueOp(param.at(0), variable);
auto add = std::make_shared<Add>(read_value, param.at(0));
auto assign = CreateAssignOp(add, variable);
auto res = std::make_shared<Result>(add);
function = std::make_shared<Function>(ResultVector{res}, SinkVector{assign}, param, "TestMemory");
}
void MemoryTest::ApplyLowLatency() {
if (transformation == ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2) {
function->validate_nodes_and_infer_types();
auto referenceInputs = std::vector<std::vector<uint8_t>>(inputs.size());
auto refInputsTypes = std::vector<element::Type>(inputs.size());
HostTensorVector inputTensors;
for (auto & input : inputs) {
const auto &dataSize = input->byteSize();
const auto &tensorDesc = input->getTensorDesc();
auto memory = InferenceEngine::as<InferenceEngine::MemoryBlob>(input);
IE_ASSERT(memory);
const auto lockedMemory = memory->wmap();
const auto buffer = lockedMemory.as<const std::uint8_t *>();
auto hostTensor = std::make_shared<HostTensor>(FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(tensorDesc.getPrecision()),
tensorDesc.getDims());
hostTensor->write(buffer, dataSize);
inputTensors.push_back(hostTensor);
}
// evaluate method is not implemented for TI op.
ngraph::pass::Manager manager;
manager.register_pass<ov::pass::UnrollTensorIterator>();
pass::Manager manager;
manager.register_pass<pass::LowLatency2>();
manager.run_passes(function);
} else if (transformation == ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2_ORIGINAL_INIT) {
function->validate_nodes_and_infer_types();
pass::Manager manager;
manager.register_pass<pass::LowLatency2>(false);
manager.run_passes(function);
const auto &outInfo = executableNetwork.GetOutputsInfo();
HostTensorVector outputTensors(outInfo.size());
for (auto& outTensor : outputTensors) {
outTensor = std::make_shared<HostTensor>();
}
OPENVINO_SUPPRESS_DEPRECATED_START
function->evaluate(outputTensors, inputTensors, eval_context);
OPENVINO_SUPPRESS_DEPRECATED_END
std::vector<std::pair<element::Type, std::vector<std::uint8_t>>> outputs(outInfo.size());
for (size_t idx = 0; idx < outInfo.size(); ++idx) {
outputs[idx].first = outputTensors[idx]->get_element_type();
outputs[idx].second.resize(outputTensors[idx]->get_size_in_bytes());
outputTensors[idx]->read(outputs[idx].second.data(), outputTensors[idx]->get_size_in_bytes());
}
return outputs;
}
void MemoryTest::CreateTIFunc() {
auto param = std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape(inputShape));
std::vector<std::vector<size_t>> shape = {{static_cast<size_t>(iteration_count), 1}};
auto iter_count = std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape{static_cast<size_t>(iteration_count), 1});
// Body
auto X = std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape(inputShape));
auto Y = std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape(inputShape));
auto Iter = std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape{1, 1});
auto add = std::make_shared<Add>(X, Y);
auto res = std::make_shared<Result>(add);
auto Iter_res = std::make_shared<Result>(Iter);
auto body = std::make_shared<Function>(OutputVector{res, Iter_res}, ParameterVector {X, Y, Iter});
// TI construction
auto tensor_iterator = std::make_shared<TensorIterator>();
tensor_iterator->set_body(body);
tensor_iterator->set_merged_input(X, param, res);
tensor_iterator->set_invariant_input(Y, param);
tensor_iterator->set_sliced_input(Iter, iter_count, 0, 1, 1, -1, 0);
auto output = tensor_iterator->get_iter_value(res, -1);
auto output_iter = tensor_iterator->get_concatenated_slices(Iter_res, 0, 1, 1, -1, 0);
function = std::make_shared<Function>(OutputVector{output, output_iter},
ParameterVector{param, iter_count},
"PureTI");
}
void MemoryTest::CreateCommonFunc() {
ov::ParameterVector param {std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape(inputShape))};
const auto variable_info = targetDevice == ov::test::utils::DEVICE_GPU ?
VariableInfo{Shape{inputShape}, ngPrc, "v0"} : VariableInfo{inputShape, ngPrc, "v0"};
auto variable = std::make_shared<Variable>(variable_info);
auto read_value = CreateReadValueOp(param.at(0), variable);
auto add = std::make_shared<Add>(read_value, param.at(0));
auto assign = CreateAssignOp(add, variable);
auto res = std::make_shared<Result>(add);
function = std::make_shared<Function>(ResultVector{res}, SinkVector{assign}, param, "TestMemory");
}
void MemoryTest::ApplyLowLatency() {
if (transformation == ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2) {
function->validate_nodes_and_infer_types();
pass::Manager manager;
manager.register_pass<pass::LowLatency2>();
manager.run_passes(function);
} else if (transformation == ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2_ORIGINAL_INIT) {
function->validate_nodes_and_infer_types();
pass::Manager manager;
manager.register_pass<pass::LowLatency2>(false);
manager.run_passes(function);
} else if (transformation == ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2_REGULAR_API) {
cnnNetwork = InferenceEngine::CNNNetwork{function};
InferenceEngine::lowLatency2(cnnNetwork, iteration_count);
}
}
}
} // namespace LayerTestsDefinitions

View File

@ -2,332 +2,357 @@
// SPDX-License-Identifier: Apache-2.0
//
#include <ie_transformations.hpp>
#include <transformations/control_flow/unroll_tensor_iterator.hpp>
#include "ngraph/pass/low_latency.hpp"
#include "ov_models/builders.hpp"
#include "shared_test_classes/subgraph/memory_LSTMCell.hpp"
#include "common_test_utils/node_builders/eltwise.hpp"
#include "functional_test_utils/core_config.hpp"
#include "common_test_utils/data_utils.hpp"
#include "functional_test_utils/skip_tests_config.hpp"
#include "openvino/op/util/variable.hpp"
#include "openvino/pass/low_latency.hpp"
#include "openvino/pass/manager.hpp"
#include "ov_models/builders.hpp"
using namespace ngraph;
using namespace opset7;
namespace SubgraphTestsDefinitions {
std::string MemoryLSTMCellTest::getTestCaseName(const testing::TestParamInfo<memoryLSTMCellParams> &obj) {
std::string targetDevice;
InferenceEngine::Precision netPrecision;
size_t inputSize;
size_t hiddenSize;
std::map<std::string, std::string> config;
ngraph::helpers::MemoryTransformation transformation;
std::tie(transformation, targetDevice, netPrecision, inputSize, hiddenSize, config) = obj.param;
std::ostringstream result;
result << "transformation=" << transformation << "_";
result << "netPrecision=" << netPrecision.name() << "_";
result << "IS=" << inputSize << "_";
result << "HS=" << hiddenSize << "_";
result << "targetDevice=" << targetDevice;
return result.str();
}
namespace ov {
namespace test {
std::string MemoryLSTMCellTest::getTestCaseName(const testing::TestParamInfo<memoryLSTMCellParams>& obj) {
std::string targetDevice;
ov::element::Type element_type;
size_t inputSize;
size_t hiddenSize;
ov::AnyMap config;
ov::test::utils::MemoryTransformation transformation;
std::tie(transformation, targetDevice, element_type, inputSize, hiddenSize, config) = obj.param;
std::ostringstream result;
result << "transformation=" << transformation << "_";
result << "ET=" << element_type << "_";
result << "IS=" << inputSize << "_";
result << "HS=" << hiddenSize << "_";
result << "targetDevice=" << targetDevice;
return result.str();
}
void MemoryLSTMCellTest::SetUp() {
InferenceEngine::Precision netPrecision;
std::map<std::string, std::string> config;
size_t inputSize;
std::tie(transformation, targetDevice, netPrecision, inputSize, hiddenSize, config) = this->GetParam();
configuration.insert(config.begin(), config.end());
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
size_t hiddenSize;
std::vector<size_t> input_dims { 1, inputSize };
std::vector<size_t> squeeze_axes {0};
std::vector<size_t> hidden_memory_dims {1, hiddenSize};
std::vector<size_t> cell_memory_dims {1, hiddenSize};
void MemoryLSTMCellTest::SetUp() {
ov::element::Type element_type;
ov::AnyMap config;
size_t inputSize;
std::tie(transformation, targetDevice, element_type, inputSize, hiddenSize, config) = this->GetParam();
configuration.insert(config.begin(), config.end());
input_bias = ov::test::utils::generate_float_numbers(inputSize, -0.2f, 0.0f);
input_weights = ov::test::utils::generate_float_numbers(inputSize, 0.0f, 0.1f);
hidden_memory_init = ov::test::utils::generate_float_numbers(hiddenSize, -0.2f, 0.2f);
cell_memory_init = ov::test::utils::generate_float_numbers(hiddenSize, -0.2f, 0.2f);
weights_vals = ov::test::utils::generate_float_numbers(4 * hiddenSize * inputSize, -0.1f, 0.1f);
reccurrenceWeights_vals = ov::test::utils::generate_float_numbers(4 * hiddenSize * hiddenSize, -0.1f, 0.1f);
bias_vals = ov::test::utils::generate_float_numbers(4 * hiddenSize, -0.2f, 0.1f);
std::vector<size_t> input_dims{1, inputSize};
std::vector<size_t> squeeze_axes{0};
std::vector<size_t> hidden_memory_dims{1, hiddenSize};
std::vector<size_t> cell_memory_dims{1, hiddenSize};
input_shapes = {input_dims};
ov::ParameterVector input_parameter {std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape(input_dims))};
input_bias = ov::test::utils::generate_float_numbers(inputSize, -0.2f, 0.0f);
input_weights = ov::test::utils::generate_float_numbers(inputSize, 0.0f, 0.1f);
hidden_memory_init = ov::test::utils::generate_float_numbers(hiddenSize, -0.2f, 0.2f);
cell_memory_init = ov::test::utils::generate_float_numbers(hiddenSize, -0.2f, 0.2f);
weights_vals = ov::test::utils::generate_float_numbers(4 * hiddenSize * inputSize, -0.1f, 0.1f);
reccurrenceWeights_vals = ov::test::utils::generate_float_numbers(4 * hiddenSize * hiddenSize, -0.1f, 0.1f);
bias_vals = ov::test::utils::generate_float_numbers(4 * hiddenSize, -0.2f, 0.1f);
auto input_add_const = builder::makeConstant(ngPrc, input_dims, input_bias);
auto add = builder::makeEltwise(input_parameter[0], input_add_const, helpers::EltwiseTypes::ADD);
ov::ParameterVector input_parameter{std::make_shared<ov::op::v0::Parameter>(element_type, ov::Shape(input_dims))};
input_parameter[0]->set_friendly_name("Parameter_1");
auto input_mul_const = builder::makeConstant(ngPrc, input_dims, input_weights);
auto mul = builder::makeEltwise(add, input_mul_const, helpers::EltwiseTypes::MULTIPLY);
auto input_add_const = ngraph::builder::makeConstant(element_type, input_dims, input_bias);
auto add = ov::test::utils::makeEltwise(input_parameter[0], input_add_const, ov::test::utils::EltwiseTypes::ADD);
auto unsqueeze_input_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_input = std::make_shared<Unsqueeze>(mul, unsqueeze_input_const);
auto input_mul_const = ngraph::builder::makeConstant(element_type, input_dims, input_weights);
auto mul = ov::test::utils::makeEltwise(add, input_mul_const, ov::test::utils::EltwiseTypes::MULTIPLY);
auto permute_in_params = std::make_shared<Constant>(element::i64, Shape{3}, Shape{{1, 0, 2}});
auto permute_in = std::make_shared<Transpose>(unsqueeze_input, permute_in_params);
auto unsqueeze_input_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_input = std::make_shared<ov::op::v0::Unsqueeze>(mul, unsqueeze_input_const);
auto cell_memory_constant = builder::makeConstant<float>(ngPrc, cell_memory_dims, cell_memory_init);
auto var_cell =
std::make_shared<Variable>(VariableInfo{PartialShape(cell_memory_dims), ngPrc, "cell_state_1"});
auto var_hidden =
std::make_shared<Variable>(VariableInfo{PartialShape(cell_memory_dims), ngPrc, "hidden_state_1"});
auto cell_memory_read = std::make_shared<ReadValue>(cell_memory_constant, var_cell);
auto permute_in_params = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{3}, Shape{{1, 0, 2}});
auto permute_in = std::make_shared<ov::op::v1::Transpose>(unsqueeze_input, permute_in_params);
auto hidden_memory_constant = builder::makeConstant<float>(ngPrc, hidden_memory_dims, hidden_memory_init);
auto hidden_memory_read = std::make_shared<ReadValue>(hidden_memory_constant, var_hidden);
auto cell_memory_constant = ngraph::builder::makeConstant<float>(element_type, cell_memory_dims, cell_memory_init);
auto var_cell =
std::make_shared<Variable>(VariableInfo{PartialShape(cell_memory_dims), element_type, "cell_state_1"});
auto var_hidden =
std::make_shared<Variable>(VariableInfo{PartialShape(cell_memory_dims), element_type, "hidden_state_1"});
auto cell_memory_read = std::make_shared<ov::op::v6::ReadValue>(cell_memory_constant, var_cell);
// Body - inputs
auto X = std::make_shared<Parameter>(ngPrc, Shape{1, 1, inputSize});
auto H_t = std::make_shared<Parameter>(ngPrc, Shape{1, hiddenSize});
auto C_t = std::make_shared<Parameter>(ngPrc, Shape{1, hiddenSize});
// Body - layers
auto squeeze_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze = std::make_shared<Squeeze>(X, squeeze_const);
auto hidden_memory_constant =
ngraph::builder::makeConstant<float>(element_type, hidden_memory_dims, hidden_memory_init);
auto hidden_memory_read = std::make_shared<ov::op::v6::ReadValue>(hidden_memory_constant, var_hidden);
auto weightsNode = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, inputSize }, weights_vals);
auto reccurrenceWeightsNode = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, hiddenSize }, reccurrenceWeights_vals);
auto biasNode = builder::makeConstant<float>(ngPrc, {4 * hiddenSize}, bias_vals);
auto lstm = std::make_shared<LSTMCell>(squeeze, H_t, C_t, weightsNode, reccurrenceWeightsNode, biasNode, hiddenSize);
// Body - inputs
auto X = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, 1, inputSize});
auto H_t = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, hiddenSize});
auto C_t = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, hiddenSize});
// Body - layers
auto squeeze_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze = std::make_shared<ov::op::v0::Squeeze>(X, squeeze_const);
auto unsqueeze_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze = std::make_shared<Unsqueeze>(lstm->output(0), unsqueeze_const);
// body - outputs
auto H_o = lstm->output(0);
auto C_o = lstm->output(1);
auto unsqueeze_o = unsqueeze->output(0);
auto weightsNode = ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, inputSize}, weights_vals);
auto reccurrenceWeightsNode =
ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, hiddenSize}, reccurrenceWeights_vals);
auto biasNode = ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize}, bias_vals);
auto lstm = std::make_shared<ov::op::v0::LSTMCell>(squeeze,
H_t,
C_t,
weightsNode,
reccurrenceWeightsNode,
biasNode,
hiddenSize);
auto body = std::make_shared<Function>(OutputVector{unsqueeze_o, H_o, C_o}, ParameterVector {X, H_t, C_t});
// TI construction
auto tensor_iterator = std::make_shared<TensorIterator>();
tensor_iterator->set_body(body);
tensor_iterator->set_sliced_input(X, permute_in, 0, 1, 1, -1, 0);
tensor_iterator->set_merged_input(H_t, hidden_memory_read, H_o);
tensor_iterator->set_merged_input(C_t, cell_memory_read, C_o);
auto unsqueeze_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze = std::make_shared<ov::op::v0::Unsqueeze>(lstm->output(0), unsqueeze_const);
// body - outputs
auto H_o = lstm->output(0);
auto C_o = lstm->output(1);
auto unsqueeze_o = unsqueeze->output(0);
auto out_unsqueeze = tensor_iterator->get_iter_value(unsqueeze_o, -1);
auto out_hidden = tensor_iterator->get_iter_value(H_o, -1);
auto out_cell = tensor_iterator->get_iter_value(C_o, -1);
auto body = std::make_shared<Model>(OutputVector{unsqueeze_o, H_o, C_o}, ParameterVector{X, H_t, C_t});
// TI construction
auto tensor_iterator = std::make_shared<ov::op::v0::TensorIterator>();
tensor_iterator->set_body(body);
tensor_iterator->set_sliced_input(X, permute_in, 0, 1, 1, -1, 0);
tensor_iterator->set_merged_input(H_t, hidden_memory_read, H_o);
tensor_iterator->set_merged_input(C_t, cell_memory_read, C_o);
auto out_unsqueeze = tensor_iterator->get_iter_value(unsqueeze_o, -1);
auto out_hidden = tensor_iterator->get_iter_value(H_o, -1);
auto out_cell = tensor_iterator->get_iter_value(C_o, -1);
out_hidden.get_tensor().set_element_type(ngPrc);
out_cell.get_tensor().set_element_type(ngPrc);
out_hidden.get_tensor().set_element_type(element_type);
out_cell.get_tensor().set_element_type(element_type);
auto cell_memory_write = std::make_shared<Assign>(out_cell, var_cell);
auto hidden_memory_write = std::make_shared<Assign>(out_hidden, var_hidden);
auto cell_memory_write = std::make_shared<ov::op::v6::Assign>(out_cell, var_cell);
auto hidden_memory_write = std::make_shared<ov::op::v6::Assign>(out_hidden, var_hidden);
auto final_reshape_pattern = std::make_shared<Constant>(element::i64, Shape{4},
std::vector<size_t>({1, 1, 1, hiddenSize}));
auto final_reshape = std::make_shared<Reshape>(out_unsqueeze, final_reshape_pattern, false);
auto final_reshape_pattern =
std::make_shared<ov::op::v0::Constant>(element::i64, Shape{4}, std::vector<size_t>({1, 1, 1, hiddenSize}));
auto final_reshape = std::make_shared<ov::op::v1::Reshape>(out_unsqueeze, final_reshape_pattern, false);
final_reshape->set_friendly_name("Reshape_1");
cell_memory_write->add_control_dependency(cell_memory_read);
hidden_memory_write->add_control_dependency(hidden_memory_read);
cell_memory_write->add_control_dependency(cell_memory_read);
hidden_memory_write->add_control_dependency(hidden_memory_read);
function = std::make_shared<Function>(OutputVector{final_reshape},
SinkVector{cell_memory_write, hidden_memory_write},
input_parameter,
"TI_with_memory");
tensor_iterator->validate_and_infer_types();
function = std::make_shared<Model>(OutputVector{final_reshape},
SinkVector{cell_memory_write, hidden_memory_write},
input_parameter,
"TI_with_memory");
tensor_iterator->validate_and_infer_types();
}
void MemoryLSTMCellTest::switch_to_friendly_model() {
ov::element::Type element_type;
ov::AnyMap config;
size_t inputSize;
std::tie(transformation, targetDevice, element_type, inputSize, hiddenSize, config) = this->GetParam();
std::vector<size_t> input_dims{1, inputSize};
std::vector<size_t> squeeze_axes{0};
std::vector<size_t> hidden_memory_dims{1, hiddenSize};
std::vector<size_t> cell_memory_dims{1, hiddenSize};
ov::ParameterVector input_parameter{std::make_shared<ov::op::v0::Parameter>(element_type, ov::Shape(input_dims))};
input_parameter[0]->set_friendly_name("Parameter_1");
auto input_add_const = ngraph::builder::makeConstant(element_type, input_dims, input_bias);
auto add = ov::test::utils::makeEltwise(input_parameter[0], input_add_const, ov::test::utils::EltwiseTypes::ADD);
auto input_mul_const = ngraph::builder::makeConstant(element_type, input_dims, input_weights);
auto mul = ov::test::utils::makeEltwise(add, input_mul_const, ov::test::utils::EltwiseTypes::MULTIPLY);
auto unsqueeze_input_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_input = std::make_shared<ov::op::v0::Unsqueeze>(mul, unsqueeze_input_const);
auto cell_memory_constant = ngraph::builder::makeConstant<float>(element_type, cell_memory_dims, cell_memory_init);
auto hidden_memory_constant =
ngraph::builder::makeConstant<float>(element_type, hidden_memory_dims, hidden_memory_init);
// Body - layers
auto squeeze_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze = std::make_shared<ov::op::v0::Squeeze>(unsqueeze_input, squeeze_const);
auto weightsNode = ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, inputSize}, weights_vals);
auto reccurrenceWeightsNode =
ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, hiddenSize}, reccurrenceWeights_vals);
auto biasNode = ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize}, bias_vals);
auto lstm = std::make_shared<ov::op::v0::LSTMCell>(squeeze,
hidden_memory_constant,
cell_memory_constant,
weightsNode,
reccurrenceWeightsNode,
biasNode,
hiddenSize,
ov::op::LSTMWeightsFormat::FICO);
auto unsqueeze_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze = std::make_shared<ov::op::v0::Unsqueeze>(lstm->output(0), unsqueeze_const);
auto final_reshape_pattern =
std::make_shared<ov::op::v0::Constant>(element::i64, Shape{4}, std::vector<size_t>({1, 1, 1, hiddenSize}));
auto final_reshape = std::make_shared<ov::op::v1::Reshape>(unsqueeze, final_reshape_pattern, false);
final_reshape->set_friendly_name("Reshape_1");
functionRefs = std::make_shared<Model>(final_reshape, input_parameter, "TI_unrolled_without_memory");
}
void MemoryLSTMCellTest::create_pure_tensor_iterator_model() {
ov::element::Type element_type;
ov::AnyMap config;
size_t inputSize;
std::tie(transformation, targetDevice, element_type, inputSize, hiddenSize, config) = this->GetParam();
std::vector<size_t> input_dims{1, inputSize};
std::vector<size_t> squeeze_axes{0};
std::vector<size_t> hidden_memory_dims{1, hiddenSize};
std::vector<size_t> cell_memory_dims{1, hiddenSize};
ov::ParameterVector input_parameter{std::make_shared<ov::op::v0::Parameter>(element_type, ov::Shape(input_dims))};
input_parameter[0]->set_friendly_name("Parameter_1");
auto input_add_const = ngraph::builder::makeConstant(element_type, input_dims, input_bias);
auto add = ov::test::utils::makeEltwise(input_parameter[0], input_add_const, ov::test::utils::EltwiseTypes::ADD);
auto input_mul_const = ngraph::builder::makeConstant(element_type, input_dims, input_weights);
auto mul = ov::test::utils::makeEltwise(add, input_mul_const, ov::test::utils::EltwiseTypes::MULTIPLY);
auto unsqueeze_input_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_input = std::make_shared<ov::op::v0::Unsqueeze>(mul, unsqueeze_input_const);
auto permute_in_params = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{3}, Shape{{1, 0, 2}});
auto permute_in = std::make_shared<ov::op::v1::Transpose>(unsqueeze_input, permute_in_params);
auto cell_memory_constant = ngraph::builder::makeConstant<float>(element_type, cell_memory_dims, cell_memory_init);
auto hidden_memory_constant =
ngraph::builder::makeConstant<float>(element_type, hidden_memory_dims, hidden_memory_init);
// Body - inputs
auto X = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, 1, inputSize});
auto H_t = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, hiddenSize});
auto C_t = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, hiddenSize});
H_t->set_friendly_name("hidden_state_1");
C_t->set_friendly_name("cell_state_1");
// Body - layers
auto squeeze_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze = std::make_shared<ov::op::v0::Squeeze>(X, squeeze_const);
auto weightsNode = ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, inputSize}, weights_vals);
auto reccurrenceWeightsNode =
ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, hiddenSize}, reccurrenceWeights_vals);
auto biasNode = ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize}, bias_vals);
auto lstm = std::make_shared<ov::op::v0::LSTMCell>(squeeze,
H_t,
C_t,
weightsNode,
reccurrenceWeightsNode,
biasNode,
hiddenSize,
ov::op::LSTMWeightsFormat::FICO);
auto unsqueeze_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze = std::make_shared<ov::op::v0::Unsqueeze>(lstm->output(0), unsqueeze_const);
// body - outputs
auto H_o = lstm->output(0);
auto C_o = lstm->output(1);
auto unsqueeze_o = unsqueeze->output(0);
auto body = std::make_shared<Model>(OutputVector{unsqueeze_o, H_o, C_o}, ParameterVector{X, H_t, C_t});
// TI construction
auto tensor_iterator = std::make_shared<ov::op::v0::TensorIterator>();
tensor_iterator->set_body(body);
tensor_iterator->set_sliced_input(X, permute_in, 0, 1, 1, -1, 0);
tensor_iterator->set_merged_input(H_t, hidden_memory_constant, H_o);
tensor_iterator->set_merged_input(C_t, cell_memory_constant, C_o);
auto out_unsqueeze = tensor_iterator->get_iter_value(unsqueeze_o, -1);
auto out_hidden = tensor_iterator->get_iter_value(H_o, -1);
auto out_cell = tensor_iterator->get_iter_value(C_o, -1);
out_hidden.get_tensor().set_element_type(element_type);
out_cell.get_tensor().set_element_type(element_type);
auto final_reshape_pattern =
std::make_shared<ov::op::v0::Constant>(element::i64, Shape{4}, std::vector<size_t>({1, 1, 1, hiddenSize}));
auto final_reshape = std::make_shared<ov::op::v1::Reshape>(out_unsqueeze, final_reshape_pattern, false);
final_reshape->set_friendly_name("Reshape_1");
functionRefs = std::make_shared<Model>(OutputVector{final_reshape, out_hidden, out_cell}, input_parameter, "PureTI");
}
void MemoryLSTMCellTest::compile_model() {
ov::test::SubgraphBaseStaticTest::compile_model();
inferRequest = compiledModel.create_infer_request();
}
void MemoryLSTMCellTest::infer() {
for (const auto& input : inputs) {
inferRequest.set_tensor(input.first, input.second);
}
inferRequest.infer();
}
void MemoryLSTMCellTest::run() {
SKIP_IF_CURRENT_TEST_IS_DISABLED()
if (transformation != ov::test::utils::MemoryTransformation::NONE) {
core_configuration(this);
apply_low_latency();
} else {
compile_model();
}
void MemoryLSTMCellTest::switchToNgraphFriendlyModel() {
InferenceEngine::Precision netPrecision;
std::map<std::string, std::string> config;
size_t inputSize;
std::tie(transformation, targetDevice, netPrecision, inputSize, hiddenSize, config) = this->GetParam();
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
init_memory();
generate_inputs(input_shapes);
std::vector<size_t> input_dims { 1, inputSize };
std::vector<size_t> squeeze_axes {0};
std::vector<size_t> hidden_memory_dims {1, hiddenSize};
std::vector<size_t> cell_memory_dims {1, hiddenSize};
ov::ParameterVector input_parameter {std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape(input_dims))};
auto input_add_const = builder::makeConstant(ngPrc, input_dims, input_bias);
auto add = builder::makeEltwise(input_parameter[0], input_add_const, helpers::EltwiseTypes::ADD);
auto input_mul_const = builder::makeConstant(ngPrc, input_dims, input_weights);
auto mul = builder::makeEltwise(add, input_mul_const, helpers::EltwiseTypes::MULTIPLY);
auto unsqueeze_input_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_input = std::make_shared<Unsqueeze>(mul, unsqueeze_input_const);
auto cell_memory_constant = builder::makeConstant<float>(ngPrc, cell_memory_dims, cell_memory_init);
auto hidden_memory_constant = builder::makeConstant<float>(ngPrc, hidden_memory_dims, hidden_memory_init);
// Body - layers
auto squeeze_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze = std::make_shared<Squeeze>(unsqueeze_input, squeeze_const);
auto weightsNode = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, inputSize }, weights_vals);
auto reccurrenceWeightsNode = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, hiddenSize }, reccurrenceWeights_vals);
auto biasNode = builder::makeConstant<float>(ngPrc, {4 * hiddenSize}, bias_vals);
auto lstm = std::make_shared<LSTMCell>(squeeze, hidden_memory_constant, cell_memory_constant, weightsNode,
reccurrenceWeightsNode, biasNode, hiddenSize);
auto unsqueeze_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze = std::make_shared<Unsqueeze>(lstm->output(0), unsqueeze_const);
auto final_reshape_pattern = std::make_shared<Constant>(element::i64,
Shape{4}, std::vector<size_t>({1, 1, 1, hiddenSize}));
auto final_reshape = std::make_shared<Reshape>(unsqueeze, final_reshape_pattern, false);
function = std::make_shared<Function>(final_reshape, input_parameter, "TI_unrolled_without_memory");
// Calculate ref values
if (transformation == ov::test::utils::MemoryTransformation::NONE) {
switch_to_friendly_model();
} else {
create_pure_tensor_iterator_model();
}
abs_threshold = 1e-2f;
validate();
}
void MemoryLSTMCellTest::CreatePureTensorIteratorModel() {
InferenceEngine::Precision netPrecision;
std::map<std::string, std::string> config;
size_t inputSize;
std::tie(transformation, targetDevice, netPrecision, inputSize, hiddenSize, config) = this->GetParam();
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
std::vector<size_t> input_dims { 1, inputSize };
std::vector<size_t> squeeze_axes {0};
std::vector<size_t> hidden_memory_dims {1, hiddenSize};
std::vector<size_t> cell_memory_dims {1, hiddenSize};
ov::ParameterVector input_parameter {std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape(input_dims))};
auto input_add_const = builder::makeConstant(ngPrc, input_dims, input_bias);
auto add = builder::makeEltwise(input_parameter[0], input_add_const, helpers::EltwiseTypes::ADD);
auto input_mul_const = builder::makeConstant(ngPrc, input_dims, input_weights);
auto mul = builder::makeEltwise(add, input_mul_const, helpers::EltwiseTypes::MULTIPLY);
auto unsqueeze_input_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_input = std::make_shared<Unsqueeze>(mul, unsqueeze_input_const);
auto permute_in_params = std::make_shared<Constant>(element::i64, Shape{3}, Shape{{1, 0, 2}});
auto permute_in = std::make_shared<Transpose>(unsqueeze_input, permute_in_params);
auto cell_memory_constant = builder::makeConstant<float>(ngPrc, cell_memory_dims, cell_memory_init);
auto hidden_memory_constant = builder::makeConstant<float>(ngPrc, hidden_memory_dims, hidden_memory_init);
// Body - inputs
auto X = std::make_shared<Parameter>(ngPrc, Shape{1, 1, inputSize});
auto H_t = std::make_shared<Parameter>(ngPrc, Shape{1, hiddenSize});
auto C_t = std::make_shared<Parameter>(ngPrc, Shape{1, hiddenSize});
H_t->set_friendly_name("hidden_state_1");
C_t->set_friendly_name("cell_state_1");
// Body - layers
auto squeeze_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze = std::make_shared<Squeeze>(X, squeeze_const);
auto weightsNode = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, inputSize }, weights_vals);
auto reccurrenceWeightsNode = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, hiddenSize }, reccurrenceWeights_vals);
auto biasNode = builder::makeConstant<float>(ngPrc, {4 * hiddenSize}, bias_vals);
auto lstm = std::make_shared<LSTMCell>(squeeze, H_t, C_t, weightsNode, reccurrenceWeightsNode, biasNode, hiddenSize);
auto unsqueeze_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze = std::make_shared<Unsqueeze>(lstm->output(0), unsqueeze_const);
// body - outputs
auto H_o = lstm->output(0);
auto C_o = lstm->output(1);
auto unsqueeze_o = unsqueeze->output(0);
auto body = std::make_shared<Function>(OutputVector{unsqueeze_o, H_o, C_o}, ParameterVector {X, H_t, C_t});
// TI construction
auto tensor_iterator = std::make_shared<TensorIterator>();
tensor_iterator->set_body(body);
tensor_iterator->set_sliced_input(X, permute_in, 0, 1, 1, -1, 0);
tensor_iterator->set_merged_input(H_t, hidden_memory_constant, H_o);
tensor_iterator->set_merged_input(C_t, cell_memory_constant, C_o);
auto out_unsqueeze = tensor_iterator->get_iter_value(unsqueeze_o, -1);
auto out_hidden = tensor_iterator->get_iter_value(H_o, -1);
auto out_cell = tensor_iterator->get_iter_value(C_o, -1);
out_hidden.get_tensor().set_element_type(ngPrc);
out_cell.get_tensor().set_element_type(ngPrc);
auto final_reshape_pattern = std::make_shared<Constant>(element::i64, Shape{4},
std::vector<size_t>({1, 1, 1, hiddenSize}));
auto final_reshape = std::make_shared<Reshape>(out_unsqueeze, final_reshape_pattern, false);
function = std::make_shared<Function>(OutputVector{final_reshape, out_hidden, out_cell}, input_parameter, "PureTI");
}
void MemoryLSTMCellTest::LoadNetwork() {
LayerTestsUtils::LayerTestsCommon::LoadNetwork();
inferRequest = executableNetwork.CreateInferRequest();
}
void MemoryLSTMCellTest::Infer() {
ConfigureInferRequest();
inferRequest.Infer();
}
void MemoryLSTMCellTest::Run() {
SKIP_IF_CURRENT_TEST_IS_DISABLED()
if (transformation != ngraph::helpers::MemoryTransformation::NONE) {
CoreConfiguration(this);
ApplyLowLatency();
void MemoryLSTMCellTest::init_memory() {
auto states = inferRequest.query_state();
for (auto& state : states) {
auto name = state.get_name();
if (name.find("cell_state_1") != std::string::npos) {
auto tensor = state.get_state();
std::memcpy(tensor.data(), cell_memory_init.data(), cell_memory_init.size() * sizeof(float));
state.set_state(tensor);
} else if (name.find("hidden_state_1") != std::string::npos) {
auto tensor = state.get_state();
std::memcpy(tensor.data(), hidden_memory_init.data(), hidden_memory_init.size() * sizeof(float));
state.set_state(tensor);
} else {
LoadNetwork();
}
InitMemory();
GenerateInputs();
Infer();
// Calculate ref values
if (transformation == ngraph::helpers::MemoryTransformation::NONE) {
switchToNgraphFriendlyModel();
} else {
CreatePureTensorIteratorModel();
}
Validate();
}
void MemoryLSTMCellTest::InitMemory() {
auto states = inferRequest.QueryState();
for (auto& state : states) {
auto name = state.GetName();
if (name.find("cell_state_1") != std::string::npos) {
auto blob = FuncTestUtils::createAndFillBlobWithFloatArray(state.GetState()->getTensorDesc(),
cell_memory_init.data(), cell_memory_init.size());
state.SetState(blob);
} else if (name.find("hidden_state_1") != std::string::npos) {
auto blob = FuncTestUtils::createAndFillBlobWithFloatArray(state.GetState()->getTensorDesc(),
hidden_memory_init.data(), hidden_memory_init.size());
state.SetState(blob);
} else {
GTEST_FAIL() << "unknown memory state";
}
GTEST_FAIL() << "unknown memory state";
}
}
}
void MemoryLSTMCellTest::ApplyLowLatency() {
// Calculate values after LowLatency transformation
CreatePureTensorIteratorModel();
if (transformation == ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2) {
function->validate_nodes_and_infer_types();
// Apply LowLatency (insert Assigns/ReadValues) and UnrollTensorIterator
void MemoryLSTMCellTest::apply_low_latency() {
// Calculate values after LowLatency transformation
create_pure_tensor_iterator_model();
function = functionRefs;
if (transformation == ov::test::utils::MemoryTransformation::LOW_LATENCY_V2) {
function->validate_nodes_and_infer_types();
// Apply LowLatency (insert Assigns/ReadValues) and UnrollTensorIterator
pass::Manager manager;
manager.register_pass<pass::LowLatency2>();
manager.run_passes(function);
bool ti_found = helpers::is_tensor_iterator_exist(function);
EXPECT_EQ(ti_found, false);
LoadNetwork();
} else if (transformation == ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2_REGULAR_API) {
cnnNetwork = InferenceEngine::CNNNetwork{function};
InferenceEngine::lowLatency2(cnnNetwork);
bool ti_found = helpers::is_tensor_iterator_exist(cnnNetwork.getFunction());
EXPECT_EQ(ti_found, false);
ConfigureNetwork();
executableNetwork = core->LoadNetwork(cnnNetwork, targetDevice, configuration);
inferRequest = executableNetwork.CreateInferRequest();
}
pass::Manager manager;
manager.register_pass<pass::LowLatency2>();
manager.run_passes(function);
bool ti_found = ngraph::helpers::is_tensor_iterator_exist(function);
EXPECT_EQ(ti_found, false);
compile_model();
}
} // namespace SubgraphTestsDefinitions
}
} // namespace test
} // namespace ov

View File

@ -2,32 +2,29 @@
// SPDX-License-Identifier: Apache-2.0
//
#include "ie_transformations.hpp"
#include "ngraph/opsets/opset7.hpp"
#include "ngraph/op/util/variable_context.hpp"
#include "ngraph/pass/low_latency.hpp"
#include "ov_models/builders.hpp"
#include "ov_models/utils/ov_helpers.hpp"
#include "shared_test_classes/subgraph/multiple_LSTMCell.hpp"
#include "common_test_utils/node_builders/eltwise.hpp"
#include "common_test_utils/data_utils.hpp"
#include "functional_test_utils/skip_tests_config.hpp"
#include "openvino/pass/low_latency.hpp"
#include "openvino/pass/manager.hpp"
#include "ov_models/builders.hpp"
using namespace ngraph;
using namespace opset7;
namespace ov {
namespace test {
namespace SubgraphTestsDefinitions {
std::string MultipleLSTMCellTest::getTestCaseName(const testing::TestParamInfo<multipleLSTMCellParams> &obj) {
std::string MultipleLSTMCellTest::getTestCaseName(const testing::TestParamInfo<multipleLSTMCellParams>& obj) {
std::string targetDevice;
InferenceEngine::Precision netPrecision;
ov::element::Type element_type;
size_t inputSize;
size_t hiddenSize;
std::map<std::string, std::string> config;
ngraph::helpers::MemoryTransformation transformation;
std::tie(transformation, targetDevice, netPrecision, inputSize, hiddenSize, config) = obj.param;
ov::AnyMap config;
ov::test::utils::MemoryTransformation transformation;
std::tie(transformation, targetDevice, element_type, inputSize, hiddenSize, config) = obj.param;
std::ostringstream result;
result << "transformation=" << transformation << "_";
result << "netPrecision=" << netPrecision.name() << "_";
result << "ET=" << element_type << "_";
result << "IS=" << inputSize << "_";
result << "HS=" << hiddenSize << "_";
result << "targetDevice=" << targetDevice;
@ -35,17 +32,17 @@ std::string MultipleLSTMCellTest::getTestCaseName(const testing::TestParamInfo<m
}
void MultipleLSTMCellTest::SetUp() {
InferenceEngine::Precision netPrecision;
std::map<std::string, std::string> config;
ov::element::Type element_type;
ov::AnyMap config;
size_t inputSize;
std::tie(transformation, targetDevice, netPrecision, inputSize, hiddenSize, config) = this->GetParam();
std::tie(transformation, targetDevice, element_type, inputSize, hiddenSize, config) = this->GetParam();
configuration.insert(config.begin(), config.end());
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
std::vector<size_t> input_dims { 1, inputSize };
std::vector<size_t> squeeze_axes {0};
std::vector<size_t> hidden_memory_dims {1, hiddenSize};
std::vector<size_t> cell_memory_dims {1, hiddenSize};
std::vector<size_t> input_dims{1, inputSize};
std::vector<size_t> squeeze_axes{0};
std::vector<size_t> hidden_memory_dims{1, hiddenSize};
std::vector<size_t> cell_memory_dims{1, hiddenSize};
input_shapes = {input_dims};
input_bias = ov::test::utils::generate_float_numbers(inputSize, -0.25f, 0.0f);
input_weights = ov::test::utils::generate_float_numbers(inputSize, 0.0f, 0.15f);
@ -56,55 +53,64 @@ void MultipleLSTMCellTest::SetUp() {
reccurrenceWeights_vals = ov::test::utils::generate_float_numbers(4 * hiddenSize * hiddenSize, -0.1f, 0.1f);
bias_vals = ov::test::utils::generate_float_numbers(4 * hiddenSize, -0.25f, 0.15f);
ov::ParameterVector input_parameter {std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape(input_dims))};
ov::ParameterVector input_parameter{std::make_shared<ov::op::v0::Parameter>(element_type, ov::Shape(input_dims))};
input_parameter[0]->set_friendly_name("Parameter_1");
auto input_add_const = builder::makeConstant(ngPrc, input_dims, input_bias);
auto add = builder::makeEltwise(input_parameter[0], input_add_const, helpers::EltwiseTypes::ADD);
auto input_add_const = ngraph::builder::makeConstant(element_type, input_dims, input_bias);
auto add = ov::test::utils::makeEltwise(input_parameter[0], input_add_const, ov::test::utils::EltwiseTypes::ADD);
auto input_mul_const = builder::makeConstant(ngPrc, input_dims, input_weights);
auto mul = builder::makeEltwise(add, input_mul_const, helpers::EltwiseTypes::MULTIPLY);
auto input_mul_const = ngraph::builder::makeConstant(element_type, input_dims, input_weights);
auto mul = ov::test::utils::makeEltwise(add, input_mul_const, ov::test::utils::EltwiseTypes::MULTIPLY);
auto unsqueeze_input_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_input = std::make_shared<Unsqueeze>(mul, unsqueeze_input_const);
auto unsqueeze_input_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_input = std::make_shared<ov::op::v0::Unsqueeze>(mul, unsqueeze_input_const);
auto permute_in_params = std::make_shared<Constant>(element::i64, Shape{3}, Shape{{1, 0, 2}});
auto permute_in = std::make_shared<Transpose>(unsqueeze_input, permute_in_params);
auto permute_in_params = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{3}, Shape{{1, 0, 2}});
auto permute_in = std::make_shared<ov::op::v1::Transpose>(unsqueeze_input, permute_in_params);
auto cell_memory_constant = builder::makeConstant<float>(ngPrc, cell_memory_dims, cell_memory_init);
auto var_cell =
std::make_shared<Variable>(VariableInfo{PartialShape::dynamic(), element::dynamic, "cell_state_1"});
auto var_hidden =
std::make_shared<Variable>(VariableInfo{PartialShape::dynamic(), element::dynamic, "hidden_state_1"});
auto cell_memory_read = std::make_shared<ReadValue>(cell_memory_constant, var_cell);
auto cell_memory_constant = ngraph::builder::makeConstant<float>(element_type, cell_memory_dims, cell_memory_init);
auto var_cell = std::make_shared<ov::op::util::Variable>(
ov::op::util::VariableInfo{PartialShape::dynamic(), element::dynamic, "cell_state_1"});
auto var_hidden = std::make_shared<ov::op::util::Variable>(
ov::op::util::VariableInfo{PartialShape::dynamic(), element::dynamic, "hidden_state_1"});
auto cell_memory_read = std::make_shared<ov::op::v6::ReadValue>(cell_memory_constant, var_cell);
cell_memory_read->set_friendly_name("cell_memory");
auto hidden_memory_constant = builder::makeConstant<float>(ngPrc, hidden_memory_dims, hidden_memory_init);
auto hidden_memory_read = std::make_shared<ReadValue>(hidden_memory_constant, var_hidden);
auto hidden_memory_constant =
ngraph::builder::makeConstant<float>(element_type, hidden_memory_dims, hidden_memory_init);
auto hidden_memory_read = std::make_shared<ov::op::v6::ReadValue>(hidden_memory_constant, var_hidden);
hidden_memory_read->set_friendly_name("hidden_memory");
// Body - inputs
auto X = std::make_shared<Parameter>(ngPrc, Shape{1, 1, inputSize});
auto H_t = std::make_shared<Parameter>(ngPrc, Shape{1, hiddenSize});
auto C_t = std::make_shared<Parameter>(ngPrc, Shape{1, hiddenSize});
auto X = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, 1, inputSize});
auto H_t = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, hiddenSize});
auto C_t = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, hiddenSize});
// Body - layers
auto squeeze_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze = std::make_shared<Squeeze>(X, squeeze_const);
auto squeeze_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze = std::make_shared<ov::op::v0::Squeeze>(X, squeeze_const);
auto weightsNode = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, inputSize }, weights_vals);
auto reccurrenceWeightsNode = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, hiddenSize }, reccurrenceWeights_vals);
auto biasNode = builder::makeConstant<float>(ngPrc, {4 * hiddenSize}, bias_vals);
auto lstm = std::make_shared<LSTMCell>(squeeze, H_t, C_t, weightsNode, reccurrenceWeightsNode, biasNode, hiddenSize);
auto weightsNode = ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, inputSize}, weights_vals);
auto reccurrenceWeightsNode =
ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, hiddenSize}, reccurrenceWeights_vals);
auto biasNode = ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize}, bias_vals);
auto lstm = std::make_shared<ov::op::v0::LSTMCell>(squeeze,
H_t,
C_t,
weightsNode,
reccurrenceWeightsNode,
biasNode,
hiddenSize);
auto unsqueeze_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze = std::make_shared<Unsqueeze>(lstm->output(0), unsqueeze_const);
auto unsqueeze_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze = std::make_shared<ov::op::v0::Unsqueeze>(lstm->output(0), unsqueeze_const);
// body - outputs
auto H_o = lstm->output(0);
auto C_o = lstm->output(1);
auto unsqueeze_o = unsqueeze->output(0);
auto body = std::make_shared<Function>(OutputVector{unsqueeze_o, H_o, C_o}, ParameterVector {X, H_t, C_t});
auto body = std::make_shared<Model>(OutputVector{unsqueeze_o, H_o, C_o}, ParameterVector{X, H_t, C_t});
// TI construction
auto tensor_iterator = std::make_shared<TensorIterator>();
auto tensor_iterator = std::make_shared<ov::op::v0::TensorIterator>();
tensor_iterator->set_body(body);
tensor_iterator->set_sliced_input(X, permute_in, 0, 1, 1, -1, 0);
tensor_iterator->set_merged_input(H_t, hidden_memory_read, H_o);
@ -115,56 +121,67 @@ void MultipleLSTMCellTest::SetUp() {
auto out_hidden = tensor_iterator->get_iter_value(H_o, -1);
auto out_cell = tensor_iterator->get_iter_value(C_o, -1);
out_hidden.get_tensor().set_element_type(ngPrc);
out_cell.get_tensor().set_element_type(ngPrc);
out_hidden.get_tensor().set_element_type(element_type);
out_cell.get_tensor().set_element_type(element_type);
auto cell_memory_write = std::make_shared<Assign>(out_cell, var_cell);
auto hidden_memory_write = std::make_shared<Assign>(out_hidden, var_hidden);
auto cell_memory_write = std::make_shared<ov::op::v6::Assign>(out_cell, var_cell);
auto hidden_memory_write = std::make_shared<ov::op::v6::Assign>(out_hidden, var_hidden);
auto first_reshape_pattern = std::make_shared<Constant>(element::i64,
Shape{4}, std::vector<size_t>({1, 1, 1, hiddenSize}));
auto first_reshape = std::make_shared<Reshape>(out_unsqueeze, first_reshape_pattern, false);
auto first_reshape_pattern =
std::make_shared<ov::op::v0::Constant>(element::i64, Shape{4}, std::vector<size_t>({1, 1, 1, hiddenSize}));
auto first_reshape = std::make_shared<ov::op::v1::Reshape>(out_unsqueeze, first_reshape_pattern, false);
// End of TI 1
auto inbetween_squeeze_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto inbetween_squeeze = std::make_shared<Squeeze>(first_reshape, inbetween_squeeze_const);
auto inbetween_squeeze_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto inbetween_squeeze = std::make_shared<ov::op::v0::Squeeze>(first_reshape, inbetween_squeeze_const);
// Second TI
auto var_cell_2 =
std::make_shared<Variable>(VariableInfo{PartialShape::dynamic(), element::dynamic, "cell_state_2"});
auto var_hidden_2 =
std::make_shared<Variable>(VariableInfo{PartialShape::dynamic(), element::dynamic, "hidden_state_2"});
auto cell_memory_2_constant = builder::makeConstant<float>(ngPrc, cell_memory_dims, cell_memory_init);
auto cell_memory_2_read = std::make_shared<ReadValue>(cell_memory_2_constant, var_cell_2);
auto var_cell_2 = std::make_shared<ov::op::util::Variable>(
ov::op::util::VariableInfo{PartialShape::dynamic(), element::dynamic, "cell_state_2"});
auto var_hidden_2 = std::make_shared<ov::op::util::Variable>(
ov::op::util::VariableInfo{PartialShape::dynamic(), element::dynamic, "hidden_state_2"});
auto cell_memory_2_constant =
ngraph::builder::makeConstant<float>(element_type, cell_memory_dims, cell_memory_init);
auto cell_memory_2_read = std::make_shared<ov::op::v6::ReadValue>(cell_memory_2_constant, var_cell_2);
cell_memory_2_read->set_friendly_name("cell_memory_2");
auto hidden_memory_2_constant = builder::makeConstant<float>(ngPrc, hidden_memory_dims, hidden_memory_init);
auto hidden_memory_2_read = std::make_shared<ReadValue>(hidden_memory_2_constant, var_hidden_2);
auto hidden_memory_2_constant =
ngraph::builder::makeConstant<float>(element_type, hidden_memory_dims, hidden_memory_init);
auto hidden_memory_2_read = std::make_shared<ov::op::v6::ReadValue>(hidden_memory_2_constant, var_hidden_2);
hidden_memory_2_read->set_friendly_name("hidden_memory_2");
// Body - inputs
auto X_2 = std::make_shared<Parameter>(ngPrc, Shape{1, 1, hiddenSize});
auto H_t_2 = std::make_shared<Parameter>(ngPrc, Shape{1, hiddenSize});
auto C_t_2 = std::make_shared<Parameter>(ngPrc, Shape{1, hiddenSize});
auto X_2 = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, 1, hiddenSize});
auto H_t_2 = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, hiddenSize});
auto C_t_2 = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, hiddenSize});
// Body - layers
auto squeeze_2_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze_2 = std::make_shared<Squeeze>(X_2, squeeze_2_const);
auto squeeze_2_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze_2 = std::make_shared<ov::op::v0::Squeeze>(X_2, squeeze_2_const);
auto weightsNode_2 = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, hiddenSize }, weights_2_vals);
auto reccurrenceWeightsNode_2 = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, hiddenSize }, reccurrenceWeights_vals);
auto biasNode_2 = builder::makeConstant<float>(ngPrc, {4 * hiddenSize}, bias_vals);
auto lstm_2 = std::make_shared<LSTMCell>(squeeze_2, H_t_2, C_t_2, weightsNode_2, reccurrenceWeightsNode_2, biasNode_2, hiddenSize);
auto weightsNode_2 =
ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, hiddenSize}, weights_2_vals);
auto reccurrenceWeightsNode_2 =
ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, hiddenSize}, reccurrenceWeights_vals);
auto biasNode_2 = ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize}, bias_vals);
auto lstm_2 = std::make_shared<ov::op::v0::LSTMCell>(squeeze_2,
H_t_2,
C_t_2,
weightsNode_2,
reccurrenceWeightsNode_2,
biasNode_2,
hiddenSize);
auto unsqueeze_2_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_2 = std::make_shared<Unsqueeze>(lstm_2->output(0), unsqueeze_2_const);
auto unsqueeze_2_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_2 = std::make_shared<ov::op::v0::Unsqueeze>(lstm_2->output(0), unsqueeze_2_const);
// body - outputs
auto H_o_2 = lstm_2->output(0);
auto C_o_2 = lstm_2->output(1);
auto unsqueeze_o_2 = unsqueeze_2->output(0);
auto body_2 = std::make_shared<Function>(OutputVector{unsqueeze_o_2, H_o_2, C_o_2}, ParameterVector {X_2, H_t_2, C_t_2});
auto body_2 =
std::make_shared<Model>(OutputVector{unsqueeze_o_2, H_o_2, C_o_2}, ParameterVector{X_2, H_t_2, C_t_2});
// TI construction
auto tensor_iterator_2 = std::make_shared<TensorIterator>();
auto tensor_iterator_2 = std::make_shared<ov::op::v0::TensorIterator>();
tensor_iterator_2->set_body(body_2);
tensor_iterator_2->set_sliced_input(X_2, inbetween_squeeze, 0, 1, 1, -1, 0);
tensor_iterator_2->set_merged_input(H_t_2, hidden_memory_2_read, H_o_2);
@ -175,154 +192,185 @@ void MultipleLSTMCellTest::SetUp() {
auto out_hidden_2 = tensor_iterator_2->get_iter_value(H_o_2, -1);
auto out_cell_2 = tensor_iterator_2->get_iter_value(C_o_2, -1);
out_hidden_2.get_tensor().set_element_type(ngPrc);
out_cell_2.get_tensor().set_element_type(ngPrc);
out_hidden_2.get_tensor().set_element_type(element_type);
out_cell_2.get_tensor().set_element_type(element_type);
auto cell_memory_2_write = std::make_shared<Assign>(out_cell_2, var_cell_2);
auto hidden_memory_2_write = std::make_shared<Assign>(out_hidden_2, var_hidden_2);
auto cell_memory_2_write = std::make_shared<ov::op::v6::Assign>(out_cell_2, var_cell_2);
auto hidden_memory_2_write = std::make_shared<ov::op::v6::Assign>(out_hidden_2, var_hidden_2);
auto final_reshape_pattern = std::make_shared<Constant>(element::i64, Shape{4}, std::vector<size_t>({1, 1, 1, hiddenSize}));
auto final_reshape = std::make_shared<Reshape>(out_unsqueeze_2, final_reshape_pattern, false);
auto final_reshape_pattern =
std::make_shared<ov::op::v0::Constant>(element::i64, Shape{4}, std::vector<size_t>({1, 1, 1, hiddenSize}));
auto final_reshape = std::make_shared<ov::op::v1::Reshape>(out_unsqueeze_2, final_reshape_pattern, false);
final_reshape->set_friendly_name("Reshape_1");
cell_memory_write->add_control_dependency(cell_memory_read);
hidden_memory_write->add_control_dependency(hidden_memory_read);
cell_memory_2_write->add_control_dependency(cell_memory_2_read);
hidden_memory_2_write->add_control_dependency(hidden_memory_2_read);
function = std::make_shared<Function>(OutputVector {final_reshape},
SinkVector{cell_memory_write, hidden_memory_write, cell_memory_2_write, hidden_memory_2_write},
input_parameter,
"TI_with_memory");
function = std::make_shared<Model>(
OutputVector{final_reshape},
SinkVector{cell_memory_write, hidden_memory_write, cell_memory_2_write, hidden_memory_2_write},
input_parameter,
"TI_with_memory");
}
void MultipleLSTMCellTest::switchToNgraphFriendlyModel() {
InferenceEngine::Precision netPrecision;
std::map<std::string, std::string> config;
void MultipleLSTMCellTest::switch_to_friendly_model() {
ov::element::Type element_type;
ov::AnyMap config;
size_t inputSize;
std::tie(transformation, targetDevice, netPrecision, inputSize, hiddenSize, config) = this->GetParam();
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
std::tie(transformation, targetDevice, element_type, inputSize, hiddenSize, config) = this->GetParam();
std::vector<size_t> input_dims { 1, inputSize };
std::vector<size_t> squeeze_axes {0};
std::vector<size_t> hidden_memory_dims {1, hiddenSize};
std::vector<size_t> cell_memory_dims {1, hiddenSize};
std::vector<size_t> input_dims{1, inputSize};
std::vector<size_t> squeeze_axes{0};
std::vector<size_t> hidden_memory_dims{1, hiddenSize};
std::vector<size_t> cell_memory_dims{1, hiddenSize};
ov::ParameterVector input_parameter {std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape(input_dims))};
ov::ParameterVector input_parameter{std::make_shared<ov::op::v0::Parameter>(element_type, ov::Shape(input_dims))};
input_parameter[0]->set_friendly_name("Parameter_1");
auto input_add_const = builder::makeConstant(ngPrc, input_dims, input_bias);
auto add = builder::makeEltwise(input_parameter[0], input_add_const, helpers::EltwiseTypes::ADD);
auto input_add_const = ngraph::builder::makeConstant(element_type, input_dims, input_bias);
auto add = ov::test::utils::makeEltwise(input_parameter[0], input_add_const, ov::test::utils::EltwiseTypes::ADD);
auto input_mul_const = builder::makeConstant(ngPrc, input_dims, input_weights);
auto mul = builder::makeEltwise(add, input_mul_const, helpers::EltwiseTypes::MULTIPLY);
auto input_mul_const = ngraph::builder::makeConstant(element_type, input_dims, input_weights);
auto mul = ov::test::utils::makeEltwise(add, input_mul_const, ov::test::utils::EltwiseTypes::MULTIPLY);
auto unsqueeze_input_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_input = std::make_shared<Unsqueeze>(mul, unsqueeze_input_const);
auto unsqueeze_input_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_input = std::make_shared<ov::op::v0::Unsqueeze>(mul, unsqueeze_input_const);
// Body 1 - layers
auto cell_memory_constant = builder::makeConstant<float>(ngPrc, cell_memory_dims, cell_memory_init);
auto cell_memory_constant = ngraph::builder::makeConstant<float>(element_type, cell_memory_dims, cell_memory_init);
auto hidden_memory_constant = builder::makeConstant<float>(ngPrc, hidden_memory_dims, hidden_memory_init);
auto hidden_memory_constant =
ngraph::builder::makeConstant<float>(element_type, hidden_memory_dims, hidden_memory_init);
auto squeeze_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze = std::make_shared<Squeeze>(unsqueeze_input, squeeze_const);
auto squeeze_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze = std::make_shared<ov::op::v0::Squeeze>(unsqueeze_input, squeeze_const);
auto weightsNode = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, inputSize }, weights_vals);
auto reccurrenceWeightsNode = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, hiddenSize }, reccurrenceWeights_vals);
auto biasNode = builder::makeConstant<float>(ngPrc, {4 * hiddenSize}, bias_vals);
auto lstm = std::make_shared<LSTMCell>(squeeze, hidden_memory_constant, cell_memory_constant, weightsNode,
reccurrenceWeightsNode, biasNode, hiddenSize);
auto weightsNode = ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, inputSize}, weights_vals);
auto reccurrenceWeightsNode =
ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, hiddenSize}, reccurrenceWeights_vals);
auto biasNode = ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize}, bias_vals);
auto lstm = std::make_shared<ov::op::v0::LSTMCell>(squeeze,
hidden_memory_constant,
cell_memory_constant,
weightsNode,
reccurrenceWeightsNode,
biasNode,
hiddenSize,
ov::op::LSTMWeightsFormat::FICO);
auto unsqueeze_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze = std::make_shared<Unsqueeze>(lstm->output(0), unsqueeze_const);
auto unsqueeze_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze = std::make_shared<ov::op::v0::Unsqueeze>(lstm->output(0), unsqueeze_const);
auto first_reshape_pattern = std::make_shared<Constant>(element::i64,
Shape{4}, std::vector<size_t>({1, 1, 1, hiddenSize}));
auto first_reshape = std::make_shared<Reshape>(unsqueeze, first_reshape_pattern, false);
auto first_reshape_pattern =
std::make_shared<ov::op::v0::Constant>(element::i64, Shape{4}, std::vector<size_t>({1, 1, 1, hiddenSize}));
auto first_reshape = std::make_shared<ov::op::v1::Reshape>(unsqueeze, first_reshape_pattern, false);
// Body 1 - end
auto inbetween_squeeze_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto inbetween_squeeze = std::make_shared<Squeeze>(first_reshape, inbetween_squeeze_const);
auto inbetween_squeeze_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto inbetween_squeeze = std::make_shared<ov::op::v0::Squeeze>(first_reshape, inbetween_squeeze_const);
// Body 2 - layers
auto cell_memory_2_constant = builder::makeConstant<float>(ngPrc, cell_memory_dims, cell_memory_init);
auto cell_memory_2_constant =
ngraph::builder::makeConstant<float>(element_type, cell_memory_dims, cell_memory_init);
auto hidden_memory_2_constant = builder::makeConstant<float>(ngPrc, hidden_memory_dims, hidden_memory_init);
auto hidden_memory_2_constant =
ngraph::builder::makeConstant<float>(element_type, hidden_memory_dims, hidden_memory_init);
auto squeeze_2_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze_2 = std::make_shared<Squeeze>(inbetween_squeeze, squeeze_2_const);
auto squeeze_2_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze_2 = std::make_shared<ov::op::v0::Squeeze>(inbetween_squeeze, squeeze_2_const);
auto weightsNode_2 = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, hiddenSize }, weights_2_vals);
auto reccurrenceWeightsNode_2 = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, hiddenSize }, reccurrenceWeights_vals);
auto biasNode_2 = builder::makeConstant<float>(ngPrc, {4 * hiddenSize}, bias_vals);
auto lstm_2 = std::make_shared<LSTMCell>(squeeze_2, hidden_memory_2_constant, cell_memory_2_constant, weightsNode_2,
reccurrenceWeightsNode_2, biasNode_2, hiddenSize);
auto weightsNode_2 =
ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, hiddenSize}, weights_2_vals);
auto reccurrenceWeightsNode_2 =
ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, hiddenSize}, reccurrenceWeights_vals);
auto biasNode_2 = ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize}, bias_vals);
auto lstm_2 = std::make_shared<ov::op::v0::LSTMCell>(squeeze_2,
hidden_memory_2_constant,
cell_memory_2_constant,
weightsNode_2,
reccurrenceWeightsNode_2,
biasNode_2,
hiddenSize,
ov::op::LSTMWeightsFormat::FICO);
auto unsqueeze_2_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_2 = std::make_shared<Unsqueeze>(lstm_2->output(0), unsqueeze_2_const);
auto unsqueeze_2_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_2 = std::make_shared<ov::op::v0::Unsqueeze>(lstm_2->output(0), unsqueeze_2_const);
auto final_reshape_pattern = std::make_shared<Constant>(element::i64,
Shape{4}, std::vector<size_t>({1, 1, 1, hiddenSize}));
auto final_reshape = std::make_shared<Reshape>(unsqueeze_2, final_reshape_pattern, false);
auto final_reshape_pattern =
std::make_shared<ov::op::v0::Constant>(element::i64, Shape{4}, std::vector<size_t>({1, 1, 1, hiddenSize}));
auto final_reshape = std::make_shared<ov::op::v1::Reshape>(unsqueeze_2, final_reshape_pattern, false);
final_reshape->set_friendly_name("Reshape_1");
// Body 2 - end
function = std::make_shared<Function>(final_reshape, input_parameter, "TI_unrolled_without_memory");
functionRefs = std::make_shared<Model>(final_reshape, input_parameter, "TI_unrolled_without_memory");
}
void MultipleLSTMCellTest::CreatePureTensorIteratorModel() {
InferenceEngine::Precision netPrecision;
std::map<std::string, std::string> config;
void MultipleLSTMCellTest::create_pure_tensor_iterator_model() {
ov::element::Type element_type;
ov::AnyMap config;
size_t inputSize;
std::tie(transformation, targetDevice, netPrecision, inputSize, hiddenSize, config) = this->GetParam();
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
std::tie(transformation, targetDevice, element_type, inputSize, hiddenSize, config) = this->GetParam();
std::vector<size_t> input_dims { 1, inputSize };
std::vector<size_t> squeeze_axes {0};
std::vector<size_t> hidden_memory_dims {1, hiddenSize};
std::vector<size_t> cell_memory_dims {1, hiddenSize};
std::vector<size_t> input_dims{1, inputSize};
std::vector<size_t> squeeze_axes{0};
std::vector<size_t> hidden_memory_dims{1, hiddenSize};
std::vector<size_t> cell_memory_dims{1, hiddenSize};
ov::ParameterVector input_parameter {std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape(input_dims))};
ov::ParameterVector input_parameter{std::make_shared<ov::op::v0::Parameter>(element_type, ov::Shape(input_dims))};
input_parameter[0]->set_friendly_name("Parameter_1");
auto input_add_const = builder::makeConstant(ngPrc, input_dims, input_bias);
auto add = builder::makeEltwise(input_parameter[0], input_add_const, helpers::EltwiseTypes::ADD);
auto input_add_const = ngraph::builder::makeConstant(element_type, input_dims, input_bias);
auto add = ov::test::utils::makeEltwise(input_parameter[0], input_add_const, ov::test::utils::EltwiseTypes::ADD);
auto input_mul_const = builder::makeConstant(ngPrc, input_dims, input_weights);
auto mul = builder::makeEltwise(add, input_mul_const, helpers::EltwiseTypes::MULTIPLY);
auto input_mul_const = ngraph::builder::makeConstant(element_type, input_dims, input_weights);
auto mul = ov::test::utils::makeEltwise(add, input_mul_const, ov::test::utils::EltwiseTypes::MULTIPLY);
auto unsqueeze_input_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_input = std::make_shared<Unsqueeze>(mul, unsqueeze_input_const);
auto unsqueeze_input_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_input = std::make_shared<ov::op::v0::Unsqueeze>(mul, unsqueeze_input_const);
auto permute_in_params = std::make_shared<Constant>(element::i64, Shape{3}, Shape{{1, 0, 2}});
auto permute_in = std::make_shared<Transpose>(unsqueeze_input, permute_in_params);
auto permute_in_params = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{3}, Shape{{1, 0, 2}});
auto permute_in = std::make_shared<ov::op::v1::Transpose>(unsqueeze_input, permute_in_params);
auto cell_memory_constant = builder::makeConstant<float>(ngPrc, cell_memory_dims, cell_memory_init);
auto cell_memory_constant = ngraph::builder::makeConstant<float>(element_type, cell_memory_dims, cell_memory_init);
auto hidden_memory_constant = builder::makeConstant<float>(ngPrc, hidden_memory_dims, hidden_memory_init);
auto hidden_memory_constant =
ngraph::builder::makeConstant<float>(element_type, hidden_memory_dims, hidden_memory_init);
// Body - inputs
auto X = std::make_shared<Parameter>(ngPrc, Shape{1, 1, inputSize});
auto H_t = std::make_shared<Parameter>(ngPrc, Shape{1, hiddenSize});
auto C_t = std::make_shared<Parameter>(ngPrc, Shape{1, hiddenSize});
auto X = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, 1, inputSize});
auto H_t = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, hiddenSize});
auto C_t = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, hiddenSize});
H_t->set_friendly_name("hidden_state_1");
C_t->set_friendly_name("cell_state_1");
// Body - layers
auto squeeze_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze = std::make_shared<Squeeze>(X, squeeze_const);
auto squeeze_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze = std::make_shared<ov::op::v0::Squeeze>(X, squeeze_const);
auto weightsNode = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, inputSize }, weights_vals);
auto reccurrenceWeightsNode = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, hiddenSize }, reccurrenceWeights_vals);
auto biasNode = builder::makeConstant<float>(ngPrc, {4 * hiddenSize}, bias_vals);
auto lstm = std::make_shared<LSTMCell>(squeeze, H_t, C_t, weightsNode, reccurrenceWeightsNode, biasNode, hiddenSize);
auto weightsNode = ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, inputSize}, weights_vals);
auto reccurrenceWeightsNode =
ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, hiddenSize}, reccurrenceWeights_vals);
auto biasNode = ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize}, bias_vals);
auto lstm = std::make_shared<ov::op::v0::LSTMCell>(squeeze,
H_t,
C_t,
weightsNode,
reccurrenceWeightsNode,
biasNode,
hiddenSize,
ov::op::LSTMWeightsFormat::FICO);
auto unsqueeze_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze = std::make_shared<Unsqueeze>(lstm->output(0), unsqueeze_const);
auto unsqueeze_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze = std::make_shared<ov::op::v0::Unsqueeze>(lstm->output(0), unsqueeze_const);
// body - outputs
auto H_o = lstm->output(0);
auto C_o = lstm->output(1);
auto unsqueeze_o = unsqueeze->output(0);
auto body = std::make_shared<Function>(OutputVector{unsqueeze_o, H_o, C_o}, ParameterVector {X, H_t, C_t});
auto body = std::make_shared<Model>(OutputVector{unsqueeze_o, H_o, C_o}, ParameterVector{X, H_t, C_t});
// TI construction
auto tensor_iterator = std::make_shared<TensorIterator>();
auto tensor_iterator = std::make_shared<ov::op::v0::TensorIterator>();
tensor_iterator->set_body(body);
tensor_iterator->set_sliced_input(X, permute_in, 0, 1, 1, -1, 0);
tensor_iterator->set_merged_input(H_t, hidden_memory_constant, H_o);
@ -332,48 +380,60 @@ void MultipleLSTMCellTest::CreatePureTensorIteratorModel() {
auto out_hidden = tensor_iterator->get_iter_value(H_o, -1);
auto out_cell = tensor_iterator->get_iter_value(C_o, -1);
out_hidden.get_tensor().set_element_type(ngPrc);
out_cell.get_tensor().set_element_type(ngPrc);
out_hidden.get_tensor().set_element_type(element_type);
out_cell.get_tensor().set_element_type(element_type);
tensor_iterator->validate_and_infer_types();
auto first_reshape_pattern = std::make_shared<Constant>(element::i64,
Shape{4}, std::vector<size_t>({1, 1, 1, hiddenSize}));
auto first_reshape = std::make_shared<Reshape>(out_unsqueeze, first_reshape_pattern, false);
auto first_reshape_pattern =
std::make_shared<ov::op::v0::Constant>(element::i64, Shape{4}, std::vector<size_t>({1, 1, 1, hiddenSize}));
auto first_reshape = std::make_shared<ov::op::v1::Reshape>(out_unsqueeze, first_reshape_pattern, false);
// End of TI 1
auto inbetween_squeeze_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto inbetween_squeeze = std::make_shared<Squeeze>(first_reshape, inbetween_squeeze_const);
auto inbetween_squeeze_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto inbetween_squeeze = std::make_shared<ov::op::v0::Squeeze>(first_reshape, inbetween_squeeze_const);
// Second TI
auto cell_memory_2_constant = builder::makeConstant<float>(ngPrc, cell_memory_dims, cell_memory_init);
auto cell_memory_2_constant =
ngraph::builder::makeConstant<float>(element_type, cell_memory_dims, cell_memory_init);
auto hidden_memory_2_constant = builder::makeConstant<float>(ngPrc, hidden_memory_dims, hidden_memory_init);
auto hidden_memory_2_constant =
ngraph::builder::makeConstant<float>(element_type, hidden_memory_dims, hidden_memory_init);
// Body - inputs
auto X_2 = std::make_shared<Parameter>(ngPrc, Shape{1, 1, hiddenSize});
auto H_t_2 = std::make_shared<Parameter>(ngPrc, Shape{1, hiddenSize});
auto C_t_2 = std::make_shared<Parameter>(ngPrc, Shape{1, hiddenSize});
auto X_2 = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, 1, hiddenSize});
auto H_t_2 = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, hiddenSize});
auto C_t_2 = std::make_shared<ov::op::v0::Parameter>(element_type, Shape{1, hiddenSize});
H_t_2->set_friendly_name("hidden_state_2");
C_t_2->set_friendly_name("cell_state_2");
// Body - layers
auto squeeze_2_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze_2 = std::make_shared<Squeeze>(X_2, squeeze_2_const);
auto squeeze_2_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto squeeze_2 = std::make_shared<ov::op::v0::Squeeze>(X_2, squeeze_2_const);
auto weightsNode_2 = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, hiddenSize }, weights_2_vals);
auto reccurrenceWeightsNode_2 = builder::makeConstant<float>(ngPrc, { 4 * hiddenSize, hiddenSize }, reccurrenceWeights_vals);
auto biasNode_2 = builder::makeConstant<float>(ngPrc, {4 * hiddenSize}, bias_vals);
auto lstm_2 = std::make_shared<LSTMCell>(squeeze_2, H_t_2, C_t_2, weightsNode_2, reccurrenceWeightsNode_2, biasNode_2, hiddenSize);
auto weightsNode_2 =
ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, hiddenSize}, weights_2_vals);
auto reccurrenceWeightsNode_2 =
ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize, hiddenSize}, reccurrenceWeights_vals);
auto biasNode_2 = ngraph::builder::makeConstant<float>(element_type, {4 * hiddenSize}, bias_vals);
auto lstm_2 = std::make_shared<ov::op::v0::LSTMCell>(squeeze_2,
H_t_2,
C_t_2,
weightsNode_2,
reccurrenceWeightsNode_2,
biasNode_2,
hiddenSize,
ov::op::LSTMWeightsFormat::FICO);
auto unsqueeze_2_const = std::make_shared<Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_2 = std::make_shared<Unsqueeze>(lstm_2->output(0), unsqueeze_2_const);
auto unsqueeze_2_const = std::make_shared<ov::op::v0::Constant>(element::i64, Shape{1}, squeeze_axes);
auto unsqueeze_2 = std::make_shared<ov::op::v0::Unsqueeze>(lstm_2->output(0), unsqueeze_2_const);
// body - outputs
auto H_o_2 = lstm_2->output(0);
auto C_o_2 = lstm_2->output(1);
auto unsqueeze_o_2 = unsqueeze_2->output(0);
auto body_2 = std::make_shared<Function>(OutputVector{unsqueeze_o_2, H_o_2, C_o_2}, ParameterVector {X_2, H_t_2, C_t_2});
auto body_2 =
std::make_shared<Model>(OutputVector{unsqueeze_o_2, H_o_2, C_o_2}, ParameterVector{X_2, H_t_2, C_t_2});
// TI construction
auto tensor_iterator_2 = std::make_shared<TensorIterator>();
auto tensor_iterator_2 = std::make_shared<ov::op::v0::TensorIterator>();
tensor_iterator_2->set_body(body_2);
tensor_iterator_2->set_sliced_input(X_2, inbetween_squeeze, 0, 1, 1, -1, 0);
tensor_iterator_2->set_merged_input(H_t_2, hidden_memory_2_constant, H_o_2);
@ -383,94 +443,82 @@ void MultipleLSTMCellTest::CreatePureTensorIteratorModel() {
auto out_hidden_2 = tensor_iterator_2->get_iter_value(H_o_2, -1);
auto out_cell_2 = tensor_iterator_2->get_iter_value(C_o_2, -1);
out_hidden_2.get_tensor().set_element_type(ngPrc);
out_cell_2.get_tensor().set_element_type(ngPrc);
out_hidden_2.get_tensor().set_element_type(element_type);
out_cell_2.get_tensor().set_element_type(element_type);
tensor_iterator_2->validate_and_infer_types();
auto final_reshape_pattern = std::make_shared<Constant>(element::i64,
Shape{4}, std::vector<size_t>({1, 1, 1, hiddenSize}));
auto final_reshape = std::make_shared<Reshape>(out_unsqueeze_2, final_reshape_pattern, false);
auto final_reshape_pattern =
std::make_shared<ov::op::v0::Constant>(element::i64, Shape{4}, std::vector<size_t>({1, 1, 1, hiddenSize}));
auto final_reshape = std::make_shared<ov::op::v1::Reshape>(out_unsqueeze_2, final_reshape_pattern, false);
final_reshape->set_friendly_name("Reshape_1");
function = std::make_shared<Function>(final_reshape, input_parameter, "PureTI");
functionRefs = std::make_shared<Model>(final_reshape, input_parameter, "PureTI");
}
void MultipleLSTMCellTest::InitMemory() {
InferenceEngine::TensorDesc state_description(InferenceEngine::Precision::FP32,
InferenceEngine::SizeVector({1, hiddenSize}),
InferenceEngine::Layout::NC);
auto states = inferRequest.QueryState();
void MultipleLSTMCellTest::init_memory() {
auto states = inferRequest.query_state();
for (auto& state : states) {
auto name = state.GetName();
if (name.find("cell_state_1") != std::string::npos) {
auto blob = FuncTestUtils::createAndFillBlobWithFloatArray(state_description,
cell_memory_init.data(), cell_memory_init.size());
state.SetState(blob);
} else if (name.find("hidden_state_1") != std::string::npos) {
auto blob = FuncTestUtils::createAndFillBlobWithFloatArray(state_description,
hidden_memory_init.data(), hidden_memory_init.size());
state.SetState(blob);
} else if (name.find("cell_state_2") != std::string::npos) {
auto blob = FuncTestUtils::createAndFillBlobWithFloatArray(state_description,
cell_memory_init.data(), cell_memory_init.size());
state.SetState(blob);
} else if (name.find("hidden_state_2") != std::string::npos) {
auto blob = FuncTestUtils::createAndFillBlobWithFloatArray(state_description,
hidden_memory_init.data(), hidden_memory_init.size());
state.SetState(blob);
auto name = state.get_name();
auto tensor = state.get_state();
if (name.find("cell_state_1") != std::string::npos || name.find("cell_state_2") != std::string::npos) {
std::memcpy(tensor.data(), cell_memory_init.data(), cell_memory_init.size() * sizeof(float));
} else if (name.find("hidden_state_1") != std::string::npos ||
name.find("hidden_state_2") != std::string::npos) {
std::memcpy(tensor.data(), hidden_memory_init.data(), hidden_memory_init.size() * sizeof(float));
} else {
GTEST_FAIL() << "unknown memory state";
}
state.set_state(tensor);
}
}
void MultipleLSTMCellTest::ApplyLowLatency() {
void MultipleLSTMCellTest::apply_low_latency() {
// Calculate values after LowLatency transformation
CreatePureTensorIteratorModel();
if (transformation == ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2) {
create_pure_tensor_iterator_model();
function = functionRefs;
if (transformation == ov::test::utils::MemoryTransformation::LOW_LATENCY_V2) {
function->validate_nodes_and_infer_types();
// Apply LowLatency (insert Assigns/ReadValues) and UnrollTensorIterator
pass::Manager manager;
ov::pass::Manager manager;
manager.register_pass<pass::LowLatency2>();
manager.run_passes(function);
bool ti_found = helpers::is_tensor_iterator_exist(function);
bool ti_found = ngraph::helpers::is_tensor_iterator_exist(function);
EXPECT_EQ(ti_found, false);
LoadNetwork();
} else if (transformation == ngraph::helpers::MemoryTransformation::LOW_LATENCY_V2_REGULAR_API) {
cnnNetwork = InferenceEngine::CNNNetwork{function};
InferenceEngine::lowLatency2(cnnNetwork);
bool ti_found = helpers::is_tensor_iterator_exist(cnnNetwork.getFunction());
EXPECT_EQ(ti_found, false);
ConfigureNetwork();
executableNetwork = core->LoadNetwork(cnnNetwork, targetDevice, configuration);
inferRequest = executableNetwork.CreateInferRequest();
compile_model();
}
}
void MultipleLSTMCellTest::LoadNetwork() {
LayerTestsUtils::LayerTestsCommon::LoadNetwork();
inferRequest = executableNetwork.CreateInferRequest();
void MultipleLSTMCellTest::compile_model() {
ov::test::SubgraphBaseStaticTest::compile_model();
inferRequest = compiledModel.create_infer_request();
}
void MultipleLSTMCellTest::Run() {
void MultipleLSTMCellTest::infer() {
for (const auto& input : inputs) {
inferRequest.set_tensor(input.first, input.second);
}
inferRequest.infer();
}
void MultipleLSTMCellTest::run() {
SKIP_IF_CURRENT_TEST_IS_DISABLED()
if (transformation != ngraph::helpers::MemoryTransformation::NONE) {
ApplyLowLatency();
if (transformation != ov::test::utils::MemoryTransformation::NONE) {
apply_low_latency();
} else {
LoadNetwork();
compile_model();
}
InitMemory();
GenerateInputs();
Infer();
init_memory();
generate_inputs(input_shapes);
// Calculate ref values
if (transformation == ngraph::helpers::MemoryTransformation::NONE) {
switchToNgraphFriendlyModel();
if (transformation == ov::test::utils::MemoryTransformation::NONE) {
switch_to_friendly_model();
} else {
CreatePureTensorIteratorModel();
create_pure_tensor_iterator_model();
}
Validate();
validate();
}
} // namespace SubgraphTestsDefinitions
} // namespace test
} // namespace ov