From 4f5230bb03a76c386b168a2382d83f6958232158 Mon Sep 17 00:00:00 2001 From: Szymon Durawa Date: Tue, 19 Jan 2021 13:26:29 +0100 Subject: [PATCH] Visitor api ti serialization (#3777) * Add on_adapter(Function) for serialization. * Add port_map and back_edges serialization. * Add 2 unit tests for TI serialization. * Convert lambda expression into function pointer. * Add single layer test for tensor iterator. * Add limitation for file name length during serialization. * Add file name length limitation for Serialize(). * Add WA for LSTMCell v0 in serialize class, new test class for TI serialization with dynamic weights, add bin path to SerializationParams, replace call to ngfunction_2_irv10 with visitor.on_attribute(). * Remove hacks for TI from ngfunction_2_irv10(), validate buffers in port_map. * Changed year in new added test files. * Add check for version of LSTMv0 WA, add assert for model read from file. * Remove append_copy for xml Function, changed comparison for LSTMvo WA. * Update second WA for LSTMCell v0 with version check. * Remove find_child when searching for port_map and back_edges. --- .../src/transformations/serialize.cpp | 167 +++++++++- .../models/ti_negative_stride.xml | 272 ++++++++++++++++ .../ir_serialization/models/ti_resnet.xml | 300 ++++++++++++++++++ .../ir_serialization/serialize.cpp | 42 ++- .../ir_serialization/tensor_iterator.cpp | 86 +++++ .../single_layer/tensor_iterator.cpp | 43 +++ .../base/layer_test_utils.hpp | 3 + .../src/base/layer_test_utils.cpp | 2 +- 8 files changed, 886 insertions(+), 29 deletions(-) create mode 100644 inference-engine/tests/functional/inference_engine/ir_serialization/models/ti_negative_stride.xml create mode 100644 inference-engine/tests/functional/inference_engine/ir_serialization/models/ti_resnet.xml create mode 100644 inference-engine/tests/functional/inference_engine/ir_serialization/tensor_iterator.cpp create mode 100644 inference-engine/tests/functional/inference_engine/serialization/single_layer/tensor_iterator.cpp diff --git a/inference-engine/src/transformations/src/transformations/serialize.cpp b/inference-engine/src/transformations/src/transformations/serialize.cpp index 2e564321679..91f46db0ba2 100644 --- a/inference-engine/src/transformations/src/transformations/serialize.cpp +++ b/inference-engine/src/transformations/src/transformations/serialize.cpp @@ -57,6 +57,11 @@ std::string translate_type_name(const std::string& name) { return name; } +void ngfunction_2_irv10(pugi::xml_node& node, + std::ostream& bin_file, + const ngraph::Function& f, + const std::map& custom_opsets); + // Some of the operators were added to wrong opsets. This is a mapping // that allows such operators to be serialized with proper opsets. // If new operators are discovered that have the same problem, the mapping @@ -76,6 +81,7 @@ class XmlSerializer : public ngraph::AttributeVisitor { pugi::xml_node& m_xml_node; std::ostream& m_bin_data; std::string& m_node_type_name; + const std::map& m_custom_opsets; template std::string create_atribute_list( @@ -86,16 +92,109 @@ class XmlSerializer : public ngraph::AttributeVisitor { public: XmlSerializer(pugi::xml_node& data, std::ostream& bin_data, - std::string& node_type_name) + std::string& node_type_name, + const std::map& custom_opsets) : m_xml_node(data) , m_bin_data(bin_data) - , m_node_type_name(node_type_name) { + , m_node_type_name(node_type_name) + , m_custom_opsets(custom_opsets) { + } + + std::vector map_type_from_body(const pugi::xml_node& xml_node, + const std::string& map_type) { + std::vector output; + for (pugi::xml_node node : xml_node.child("body").child("layers")) { + if (!map_type.compare(node.attribute("type").value())) { + output.push_back(node.attribute("id").value()); + } + } + + // ops for serialized body function are provided in reversed order + std::reverse(output.begin(), output.end()); + + return output; } void on_adapter(const std::string& name, ngraph::ValueAccessor& adapter) override { (void)name; - (void)adapter; + + if (m_xml_node.parent().child("body")) { + // parameters and results from body are required for port_map attributes serialization + std::vector parameter_mapping = map_type_from_body(m_xml_node.parent(), "Parameter"); + std::vector result_mapping = map_type_from_body(m_xml_node.parent(), "Result"); + + NGRAPH_CHECK(!parameter_mapping.empty() || !result_mapping.empty(), "No parameters or results found in body Function."); + + // TI, Loop do not have attributtes as regular ops, it is necessary to append "port_map" and + // "back_edges" to layer above (m_xml_node.parent()) as in ngfunction_2_irv10() layer (here "m_xml_node") + // with empty attributes is removed. + if (const auto& a = ngraph::as_type>>>(&adapter)) { + pugi::xml_node port_map = m_xml_node.parent().child("port_map"); + if (!m_xml_node.parent().child("port_map")) { + port_map = m_xml_node.parent().insert_child_before("port_map", m_xml_node.parent().first_child()); + } + + for (const auto& input_description : a->get()) { + pugi::xml_node input = port_map.append_child("input"); + input.append_attribute("external_port_id").set_value(input_description->m_input_index); + input.append_attribute("internal_layer_id").set_value(parameter_mapping[input_description->m_body_parameter_index].c_str()); + + if (auto slice_input = as_type_ptr(input_description)) { + input.prepend_attribute("axis").set_value(slice_input->m_axis); + if (slice_input->m_start) { + input.append_attribute("start").set_value(slice_input->m_start); + } + if (slice_input->m_end != -1) { + input.append_attribute("end").set_value(slice_input->m_end); + } + if (slice_input->m_stride != 1) { + input.append_attribute("stride").set_value(slice_input->m_stride); + } + if (slice_input->m_part_size != 1) { + input.append_attribute("part_size").set_value(slice_input->m_part_size); + } + } else if (auto merged_input = as_type_ptr(input_description)) { + pugi::xml_node back_edges = m_xml_node.parent().child("back_edges"); + if (!back_edges) { + back_edges = m_xml_node.parent().insert_child_after("back_edges", port_map); + } + pugi::xml_node edge = back_edges.append_child("edge"); + edge.append_attribute("from-layer").set_value(result_mapping[merged_input->m_body_value_index].c_str()); + edge.append_attribute("to-layer").set_value(parameter_mapping[merged_input->m_body_parameter_index].c_str()); + } + } + } else if (const auto& a = ngraph::as_type>>>(&adapter)) { + pugi::xml_node port_map = m_xml_node.parent().find_child([](pugi::xml_node node) {return strcmp(node.name(), "port_map") == 0;}); + if (!port_map) { + port_map = m_xml_node.parent().insert_child_before("port_map", m_xml_node.parent().first_child()); + } + + for (const auto& output_description : a->get()) { + pugi::xml_node output = port_map.append_child("output"); + output.append_attribute("external_port_id").set_value(parameter_mapping.size() + output_description->m_output_index); + output.append_attribute("internal_layer_id").set_value(result_mapping[output_description->m_body_value_index].c_str()); + + if (auto concat_output = as_type_ptr(output_description)) { + output.prepend_attribute("axis").set_value(concat_output->m_axis); + if (concat_output->m_start) { + output.append_attribute("start").set_value(concat_output->m_start); + } + if (concat_output->m_end != -1) { + output.append_attribute("end").set_value(concat_output->m_end); + } + if (concat_output->m_stride != 1) { + output.append_attribute("stride").set_value(concat_output->m_stride); + } + if (concat_output->m_part_size != 1) { + output.append_attribute("part_size").set_value(concat_output->m_part_size); + } + } + } + } + } } void on_adapter(const std::string& name, @@ -165,6 +264,23 @@ public: m_xml_node.append_attribute(name.c_str()) .set_value(create_atribute_list(adapter).c_str()); } + void on_adapter( + const std::string& name, + ngraph::ValueAccessor>& adapter) override { + if (name == "body") { + // TI, Loop do not have attributtes as regular ops, it is necessary to append "body" + // to layer above (m_xml_node.parent()) as in ngfunction_2_irv10() layer (m_xml_node) with empty attributes + // is removed. + pugi::xml_node xml_body = m_xml_node.parent().append_child(name.c_str()); + ngfunction_2_irv10(xml_body, m_bin_data, *adapter.get(), m_custom_opsets); + xml_body.first_child().remove_attribute("name"); + xml_body.first_child().remove_attribute("version"); + } else if (name == "net") { + ngfunction_2_irv10(m_xml_node, m_bin_data, *adapter.get(), m_custom_opsets); + } else { + NGRAPH_CHECK(false, "Unsupported Function name."); + } + } }; void visit_exec_graph_node(pugi::xml_node& data, std::string& node_type_name, @@ -393,13 +509,12 @@ bool resolve_dynamic_shapes(const ngraph::Function& f) { return true; } -void ngfunction_2_irv10(pugi::xml_document& doc, +void ngfunction_2_irv10(pugi::xml_node& netXml, std::ostream& bin_file, const ngraph::Function& f, const std::map& custom_opsets) { const bool exec_graph = is_exec_graph(f); - pugi::xml_node netXml = doc.append_child("net"); netXml.append_attribute("name").set_value(f.get_friendly_name().c_str()); netXml.append_attribute("version").set_value("10"); pugi::xml_node layers = netXml.append_child("layers"); @@ -424,24 +539,25 @@ void ngfunction_2_irv10(pugi::xml_document& doc, layer.append_attribute("version").set_value( get_opset_name(node, custom_opsets).c_str()); } + // pugi::xml_node data = layer.append_child("data"); + std::string node_type_name{node->get_type_name()}; // general attributes - std::string node_type_name{node->get_type_name()}; if (exec_graph) { visit_exec_graph_node(data, node_type_name, node); } else { - XmlSerializer visitor(data, bin_file, node_type_name); + XmlSerializer visitor(data, bin_file, node_type_name, custom_opsets); NGRAPH_CHECK(node->visit_attributes(visitor), "Visitor API is not supported in ", node); } layer_type_attribute.set_value( translate_type_name(node_type_name).c_str()); - const auto data_attr_size = - std::distance(data.attributes().begin(), data.attributes().end()); - if (data_attr_size == 0) { + const bool data_attr_size = + data.attributes().begin() == data.attributes().end(); + if (data_attr_size) { layer.remove_child(data); } @@ -453,6 +569,15 @@ void ngfunction_2_irv10(pugi::xml_document& doc, NGRAPH_CHECK(i.get_partial_shape().is_static(), "Unsupported dynamic input shape in ", node); + // WA for LSTMCellv0, peephole input shall not be serialized + if (i.get_index() == 6) { + auto type_info = node->get_type_info(); + if (!strcmp(type_info.name, "LSTMCell") && type_info.version == 0) { + port_id++; + continue; + } + } + pugi::xml_node port = input.append_child("port"); port.append_attribute("id").set_value(port_id++); for (auto d : i.get_shape()) { @@ -461,6 +586,10 @@ void ngfunction_2_irv10(pugi::xml_document& doc, .set_value(std::to_string(d).c_str()); } } + + if (node_type_name == "TensorIterator") { + layer.prepend_move(input); + } } // if ((node->get_output_size() > 0) && !ngraph::op::is_output(node)) { @@ -479,12 +608,22 @@ void ngfunction_2_irv10(pugi::xml_document& doc, .set_value(std::to_string(d).c_str()); } } + if (node_type_name == "TensorIterator") { + layer.insert_move_after(output, layer.first_child()); + } } } // const std::vector edge_mapping = create_edge_mapping(layer_ids, f); pugi::xml_node edges = netXml.append_child("edges"); for (auto e : edge_mapping) { + // WA for LSTMCellv0, peephole input shall not be serialized + if (e.to_port == 6) { + auto type_info = f.get_ordered_ops()[e.to_layer]->get_type_info(); + if (!strcmp(type_info.name, "LSTMCell") && type_info.version == 0) { + continue; + } + } pugi::xml_node edge = edges.append_child("edge"); edge.append_attribute("from-layer").set_value(e.from_layer); edge.append_attribute("from-port").set_value(e.from_port); @@ -496,7 +635,6 @@ void ngfunction_2_irv10(pugi::xml_document& doc, f.validate_nodes_and_infer_types(); } } - } // namespace // ! [function_pass:serialize_cpp] @@ -509,7 +647,12 @@ bool pass::Serialize::run_on_function(std::shared_ptr f) { NGRAPH_CHECK(bin_file, "Can't open bin file: \"" + m_binPath + "\""); switch (m_version) { case Version::IR_V10: - ngfunction_2_irv10(xml_doc, bin_file, *f, m_custom_opsets); + { + std::string name = "net"; + pugi::xml_node net_node = xml_doc.append_child(name.c_str()); + XmlSerializer visitor(net_node, bin_file, name, m_custom_opsets); + visitor.on_attribute(name, f); + } break; default: NGRAPH_UNREACHABLE("Unsupported version"); diff --git a/inference-engine/tests/functional/inference_engine/ir_serialization/models/ti_negative_stride.xml b/inference-engine/tests/functional/inference_engine/ir_serialization/models/ti_negative_stride.xml new file mode 100644 index 00000000000..b297fa06da5 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/ir_serialization/models/ti_negative_stride.xml @@ -0,0 +1,272 @@ + + + + + + + + 1 + 25 + 512 + + + + + + + + 1 + 256 + + + + + + + + 1 + 256 + + + + + + + 1 + 25 + 512 + + + 1 + 256 + + + 1 + 256 + + + + + 1 + 25 + 256 + + + + + + + + + + + + + + + + + + + 1 + 1 + 512 + + + + + + + + 2 + + + + + + + + 1 + 1 + 512 + + + 2 + + + + + 1 + 512 + + + + + + + + 1 + 256 + + + + + + + + 1 + 256 + + + + + + + + 1024 + 512 + + + + + + + + 1024 + 256 + + + + + + + + 1024 + + + + + + + + 1 + 512 + + + 1 + 256 + + + 1 + 256 + + + 1024 + 512 + + + 1024 + 256 + + + 1024 + + + + + 1 + 256 + + + 1 + 256 + + + + + + + 1 + 256 + + + + + + + 1 + 256 + + + + + + + + 3 + + + + + + + + 1 + 256 + + + 3 + + + + + 1 + 1 + 256 + + + + + + + 1 + 1 + 256 + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 25 + 256 + + + + + + + + + + + \ No newline at end of file diff --git a/inference-engine/tests/functional/inference_engine/ir_serialization/models/ti_resnet.xml b/inference-engine/tests/functional/inference_engine/ir_serialization/models/ti_resnet.xml new file mode 100644 index 00000000000..f35e6346e39 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/ir_serialization/models/ti_resnet.xml @@ -0,0 +1,300 @@ + + + + + + + + 16 + 1 + 512 + + + + + + + + 1 + 512 + + + + + + + + 1 + 512 + + + + + + + 16 + 1 + 512 + + + 1 + 512 + + + 1 + 512 + + + + + 16 + 1 + 512 + + + 1 + 512 + + + 1 + 512 + + + + + + + + + + + + + + + + + + + + + 1 + 1 + 512 + + + + + + + + 2 + + + + + + + + 1 + 1 + 512 + + + 2 + + + + + 1 + 512 + + + + + + + + 1 + 512 + + + + + + + + 1 + 512 + + + + + + + + 2048 + 512 + + + + + + + + 2048 + 512 + + + + + + + + 2048 + + + + + + + + 1 + 512 + + + 1 + 512 + + + 1 + 512 + + + 2048 + 512 + + + 2048 + 512 + + + 2048 + + + + + 1 + 512 + + + 1 + 512 + + + + + + + 1 + 512 + + + + + + + 1 + 512 + + + + + + + + 3 + + + + + + + + 1 + 512 + + + 3 + + + + + 1 + 1 + 512 + + + + + + + 1 + 1 + 512 + + + + + + + + + + + + + + + + + + + + + + + + + 16 + 1 + 512 + + + + + + + 1 + 512 + + + + + + + 1 + 512 + + + + + + + + + + + + + \ No newline at end of file diff --git a/inference-engine/tests/functional/inference_engine/ir_serialization/serialize.cpp b/inference-engine/tests/functional/inference_engine/ir_serialization/serialize.cpp index 7d36639d06f..dd76caa1b5b 100644 --- a/inference-engine/tests/functional/inference_engine/ir_serialization/serialize.cpp +++ b/inference-engine/tests/functional/inference_engine/ir_serialization/serialize.cpp @@ -12,17 +12,21 @@ #define IR_SERIALIZATION_MODELS_PATH "" #endif -typedef std::tuple SerializationParams; +typedef std::tuple SerializationParams; class SerializationTest: public CommonTestUtils::TestsCommon, public testing::WithParamInterface { public: std::string m_model_path; + std::string m_binary_path; std::string m_out_xml_path; std::string m_out_bin_path; void SetUp() override { m_model_path = IR_SERIALIZATION_MODELS_PATH + std::get<0>(GetParam()); + if (!std::get<1>(GetParam()).empty()) { + m_binary_path = IR_SERIALIZATION_MODELS_PATH + std::get<1>(GetParam()); + } const std::string test_name = GetTestName() + "_" + GetTimestamp(); m_out_xml_path = test_name + ".xml"; @@ -37,7 +41,13 @@ public: TEST_P(SerializationTest, CompareFunctions) { InferenceEngine::Core ie; - auto expected = ie.ReadNetwork(m_model_path); + InferenceEngine::CNNNetwork expected; + + if (!m_binary_path.empty()) { + expected = ie.ReadNetwork(m_model_path, m_binary_path); + } else { + expected = ie.ReadNetwork(m_model_path); + } expected.serialize(m_out_xml_path, m_out_bin_path); auto result = ie.ReadNetwork(m_out_xml_path, m_out_bin_path); @@ -48,19 +58,19 @@ TEST_P(SerializationTest, CompareFunctions) { } INSTANTIATE_TEST_CASE_P(IRSerialization, SerializationTest, - testing::Values(std::make_tuple("add_abc.xml"), - std::make_tuple("add_abc_f64.xml"), - std::make_tuple("split_equal_parts_2d.xml"), - std::make_tuple("addmul_abc.xml"), - std::make_tuple("add_abc_initializers.xml"), - std::make_tuple("experimental_detectron_roi_feature_extractor.xml"), - std::make_tuple("experimental_detectron_detection_output.xml"), - std::make_tuple("experimental_detectron_detection_output_opset6.xml"), - std::make_tuple("nms5.xml"), - std::make_tuple("shape_of.xml"))); + testing::Values(std::make_tuple("add_abc.xml", "add_abc.bin"), + std::make_tuple("add_abc_f64.xml", ""), + std::make_tuple("split_equal_parts_2d.xml", "split_equal_parts_2d.bin"), + std::make_tuple("addmul_abc.xml", "addmul_abc.bin"), + std::make_tuple("add_abc_initializers.xml", "add_abc_initializers.bin"), + std::make_tuple("experimental_detectron_roi_feature_extractor.xml", ""), + std::make_tuple("experimental_detectron_detection_output.xml", ""), + std::make_tuple("experimental_detectron_detection_output_opset6.xml", ""), + std::make_tuple("nms5.xml", "nms5.bin"), + std::make_tuple("shape_of.xml", ""))); INSTANTIATE_TEST_CASE_P(ONNXSerialization, SerializationTest, - testing::Values(std::make_tuple("add_abc.prototxt"), - std::make_tuple("split_equal_parts_2d.prototxt"), - std::make_tuple("addmul_abc.prototxt"), - std::make_tuple("add_abc_initializers.prototxt"))); + testing::Values(std::make_tuple("add_abc.prototxt", ""), + std::make_tuple("split_equal_parts_2d.prototxt", ""), + std::make_tuple("addmul_abc.prototxt", ""), + std::make_tuple("add_abc_initializers.prototxt", ""))); \ No newline at end of file diff --git a/inference-engine/tests/functional/inference_engine/ir_serialization/tensor_iterator.cpp b/inference-engine/tests/functional/inference_engine/ir_serialization/tensor_iterator.cpp new file mode 100644 index 00000000000..79a7a3d5dc5 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/ir_serialization/tensor_iterator.cpp @@ -0,0 +1,86 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "common_test_utils/ngraph_test_utils.hpp" +#include "gtest/gtest.h" +#include "ie_core.hpp" +#include "ie_blob.h" +#include "common_test_utils/data_utils.hpp" + +#ifndef IR_SERIALIZATION_MODELS_PATH // should be already defined by cmake +#define IR_SERIALIZATION_MODELS_PATH "" +#endif + +class SerializationTensorIteratorTest : public ::testing::Test { +protected: + std::string test_name = + ::testing::UnitTest::GetInstance()->current_test_info()->name(); + std::string m_out_xml_path = test_name + ".xml"; + std::string m_out_bin_path = test_name + ".bin"; + + void TearDown() override { + std::remove(m_out_xml_path.c_str()); + std::remove(m_out_xml_path.c_str()); + } + + void serialize_and_compare(const std::string& model_path, InferenceEngine::Blob::Ptr weights) { + std::stringstream buffer; + InferenceEngine::Core ie; + + std::ifstream model(model_path); + ASSERT_TRUE(model); + buffer << model.rdbuf(); + + auto expected = ie.ReadNetwork(buffer.str(), weights); + expected.serialize(m_out_xml_path, m_out_bin_path); + auto result = ie.ReadNetwork(m_out_xml_path, m_out_bin_path); + + bool success; + std::string message; + std::tie(success, message) = compare_functions(result.getFunction(), expected.getFunction(), true); + ASSERT_TRUE(success) << message; + } +}; + +TEST_F(SerializationTensorIteratorTest, TiResnet) { + const std::string model_path = IR_SERIALIZATION_MODELS_PATH "ti_resnet.xml"; + + size_t weights_size = 8396840; + + auto weights = InferenceEngine::make_shared_blob( + InferenceEngine::TensorDesc(InferenceEngine::Precision::U8, {weights_size}, InferenceEngine::Layout::C)); + weights->allocate(); + CommonTestUtils::fill_data(weights->buffer().as(), weights->size() / sizeof(float)); + + auto *data = weights->buffer().as(); + data[0] = 1; + data[1] = 512; + data[1049602] = 1; + data[1049603] = 1; + data[1049604] = 512; + + serialize_and_compare(model_path, weights); +} + +TEST_F(SerializationTensorIteratorTest, TiNegativeStride) { + const std::string model_path = IR_SERIALIZATION_MODELS_PATH "ti_negative_stride.xml"; + + size_t weights_size = 3149864; + + auto weights = InferenceEngine::make_shared_blob( + InferenceEngine::TensorDesc(InferenceEngine::Precision::U8, {weights_size}, InferenceEngine::Layout::C)); + weights->allocate(); + CommonTestUtils::fill_data(weights->buffer().as(), weights->size() / sizeof(float)); + + auto *data = weights->buffer().as(); + data[0] = 1; + data[1] = 512; + data[393730] = 1; + data[393731] = 1; + data[393732] = 256; + + serialize_and_compare(model_path, weights); +} diff --git a/inference-engine/tests/functional/inference_engine/serialization/single_layer/tensor_iterator.cpp b/inference-engine/tests/functional/inference_engine/serialization/single_layer/tensor_iterator.cpp new file mode 100644 index 00000000000..6326cfeacc7 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/serialization/single_layer/tensor_iterator.cpp @@ -0,0 +1,43 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "common_test_utils/test_constants.hpp" +#include "shared_test_classes/single_layer/tensor_iterator.hpp" + +using namespace LayerTestsDefinitions; + +namespace { +TEST_P(TensorIteratorTest, Serialize) { + Serialize(); +} + +const std::vector netPrecisions = { + InferenceEngine::Precision::FP32, InferenceEngine::Precision::FP16}; +const std::vector body = { + ngraph::helpers::TensorIteratorBody::GRU, ngraph::helpers::TensorIteratorBody::LSTM, ngraph::helpers::TensorIteratorBody::RNN}; +const std::vector decompose = {true, false}; +const std::vector sequenceLength = {2}; +const std::vector batch = {1, 10}; +const std::vector hiddenSize = {128}; +const std::vector sequenceAxis = {1}; +const std::vector clip = {0.f}; +const std::vector direction = { + ngraph::op::RecurrentSequenceDirection::FORWARD, ngraph::op::RecurrentSequenceDirection::REVERSE}; + +INSTANTIATE_TEST_CASE_P(smoke_TensorIterator, TensorIteratorTest, + ::testing::Combine( + ::testing::ValuesIn(decompose), + ::testing::ValuesIn(sequenceLength), + ::testing::ValuesIn(batch), + ::testing::ValuesIn(hiddenSize), + ::testing::ValuesIn(sequenceAxis), + ::testing::ValuesIn(clip), + ::testing::ValuesIn(body), + ::testing::ValuesIn(direction), + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + TensorIteratorTest::getTestCaseName); +} // namespace diff --git a/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/base/layer_test_utils.hpp b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/base/layer_test_utils.hpp index f65f68a8551..5a7170b5aaa 100644 --- a/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/base/layer_test_utils.hpp +++ b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/base/layer_test_utils.hpp @@ -31,6 +31,9 @@ namespace LayerTestsUtils { +// filename length limitation due to Windows constraints (max 256 characters) +constexpr std::size_t maxFileNameLength = 140; + class Summary; class SummaryDestroyer { diff --git a/inference-engine/tests/functional/shared_test_classes/src/base/layer_test_utils.cpp b/inference-engine/tests/functional/shared_test_classes/src/base/layer_test_utils.cpp index 6c5dabc8039..403387b2899 100644 --- a/inference-engine/tests/functional/shared_test_classes/src/base/layer_test_utils.cpp +++ b/inference-engine/tests/functional/shared_test_classes/src/base/layer_test_utils.cpp @@ -195,7 +195,7 @@ void LayerTestsCommon::Run() { void LayerTestsCommon::Serialize() { SKIP_IF_CURRENT_TEST_IS_DISABLED(); - std::string output_name = GetTestName() + "_" + GetTimestamp(); + std::string output_name = GetTestName().substr(0, maxFileNameLength) + "_" + GetTimestamp(); std::string out_xml_path = output_name + ".xml"; std::string out_bin_path = output_name + ".bin";