* Change IRv10 serialisation to not reorder parameters and results * Add tests * Fix1
This commit is contained in:
parent
2281a0ef78
commit
6f6e4093b9
|
|
@ -255,11 +255,6 @@ class XmlSerializer : public ngraph::AttributeVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
if (ir_version < 11) {
|
||||
// ops for serialized body function are provided in reversed order
|
||||
std::reverse(output.begin(), output.end());
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
|
@ -804,7 +799,9 @@ void ngfunction_2_ir(pugi::xml_node& netXml,
|
|||
const bool exec_graph = is_exec_graph(f);
|
||||
|
||||
auto sorted_ops = f.get_ordered_ops();
|
||||
if (version >= 11) {
|
||||
// get_ordered_ops() returns operations after a topological sort. The topological sort reverses order of Parameters
|
||||
// and Results. So we need to put them into sorted_ops separately to ensure correct order of inputs and outputs.
|
||||
{
|
||||
std::vector<std::shared_ptr<ov::Node>> result;
|
||||
result.reserve(sorted_ops.size());
|
||||
for (const auto& param : f.get_parameters()) {
|
||||
|
|
|
|||
|
|
@ -5,22 +5,47 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
|
||||
#include "common_test_utils/file_utils.hpp"
|
||||
#include "openvino/opsets/opset1.hpp"
|
||||
#include "openvino/pass/serialize.hpp"
|
||||
#include "openvino/util/file_util.hpp"
|
||||
#include "read_ir.hpp"
|
||||
#include "util/test_common.hpp"
|
||||
|
||||
class SerializationDeterministicityTest : public ov::test::TestsCommon {
|
||||
class DeterministicityCommon {
|
||||
protected:
|
||||
std::string test_name = GetTestName();
|
||||
std::string m_out_xml_path_1 = test_name + "1" + ".xml";
|
||||
std::string m_out_bin_path_1 = test_name + "1" + ".bin";
|
||||
std::string m_out_xml_path_2 = test_name + "2" + ".xml";
|
||||
std::string m_out_bin_path_2 = test_name + "2" + ".bin";
|
||||
std::string generateTestFilePrefix() {
|
||||
// Generate unique file names based on test name, thread id and timestamp
|
||||
// This allows execution of tests in parallel (stress mode)
|
||||
auto testInfo = ::testing::UnitTest::GetInstance()->current_test_info();
|
||||
std::string testName = testInfo->test_case_name();
|
||||
testName += testInfo->name();
|
||||
testName = std::to_string(std::hash<std::string>()(testName));
|
||||
std::stringstream ss;
|
||||
auto ts = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
std::chrono::high_resolution_clock::now().time_since_epoch());
|
||||
ss << testName << "_" << std::this_thread::get_id() << "_" << ts.count();
|
||||
testName = ss.str();
|
||||
return testName;
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
std::string m_out_xml_path_1{};
|
||||
std::string m_out_bin_path_1{};
|
||||
std::string m_out_xml_path_2{};
|
||||
std::string m_out_bin_path_2{};
|
||||
std::string filePrefix{};
|
||||
|
||||
void SetupFileNames() {
|
||||
filePrefix = generateTestFilePrefix();
|
||||
m_out_xml_path_1 = filePrefix + "1" + ".xml";
|
||||
m_out_bin_path_1 = filePrefix + "1" + ".bin";
|
||||
m_out_xml_path_2 = filePrefix + "2" + ".xml";
|
||||
m_out_bin_path_2 = filePrefix + "2" + ".bin";
|
||||
}
|
||||
|
||||
void RemoveFiles() {
|
||||
std::remove(m_out_xml_path_1.c_str());
|
||||
std::remove(m_out_xml_path_2.c_str());
|
||||
std::remove(m_out_bin_path_1.c_str());
|
||||
|
|
@ -47,6 +72,17 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
class SerializationDeterministicityTest : public ov::test::TestsCommon, public DeterministicityCommon {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
SetupFileNames();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
RemoveFiles();
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef ENABLE_OV_ONNX_FRONTEND
|
||||
|
||||
TEST_F(SerializationDeterministicityTest, BasicModel) {
|
||||
|
|
@ -122,3 +158,158 @@ TEST_F(SerializationDeterministicityTest, ModelWithConstants) {
|
|||
ASSERT_TRUE(files_equal(xml_1, xml_2));
|
||||
ASSERT_TRUE(files_equal(bin_1, bin_2));
|
||||
}
|
||||
|
||||
class SerializationDeterministicityInputOutputTest : public testing::TestWithParam<ov::pass::Serialize::Version>,
|
||||
public DeterministicityCommon {
|
||||
protected:
|
||||
std::string input0Name{"input0"};
|
||||
std::string input1Name{"input1"};
|
||||
std::string output0Name{"output0"};
|
||||
std::string output1Name{"output1"};
|
||||
|
||||
std::string xmlFileName{};
|
||||
|
||||
void SetupFileNames() {
|
||||
DeterministicityCommon::SetupFileNames();
|
||||
xmlFileName = filePrefix + "_TestModel.xml";
|
||||
}
|
||||
|
||||
void RemoveFiles() {
|
||||
DeterministicityCommon::RemoveFiles();
|
||||
std::remove(xmlFileName.c_str());
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
SetupFileNames();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
RemoveFiles();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(SerializationDeterministicityInputOutputTest, FromOvModel) {
|
||||
auto irVersion = GetParam();
|
||||
|
||||
std::shared_ptr<ov::Model> modelRef;
|
||||
{
|
||||
auto parameter0 = std::make_shared<ov::opset1::Parameter>(ov::element::f32, ov::Shape{1, 3, 22, 22});
|
||||
parameter0->set_friendly_name("input0");
|
||||
auto result0 = std::make_shared<ov::opset1::Result>(parameter0);
|
||||
result0->set_friendly_name("output0");
|
||||
auto parameter1 = std::make_shared<ov::opset1::Parameter>(ov::element::f32, ov::Shape{1, 3, 22, 22});
|
||||
parameter1->set_friendly_name("input1");
|
||||
auto result1 = std::make_shared<ov::opset1::Result>(parameter1);
|
||||
result1->set_friendly_name("output1");
|
||||
modelRef =
|
||||
std::make_shared<ov::Model>(ov::NodeVector{result0, result1}, ov::ParameterVector{parameter0, parameter1});
|
||||
}
|
||||
|
||||
auto& expected1 = modelRef;
|
||||
ov::pass::Serialize(m_out_xml_path_1, m_out_bin_path_1, irVersion).run_on_model(modelRef);
|
||||
auto expected2 = ov::test::readModel(m_out_xml_path_1, m_out_bin_path_1);
|
||||
ov::pass::Serialize(m_out_xml_path_2, m_out_bin_path_2, irVersion).run_on_model(expected2);
|
||||
|
||||
EXPECT_EQ(input0Name, expected1->input(0).get_node()->get_friendly_name());
|
||||
EXPECT_EQ(input1Name, expected1->input(1).get_node()->get_friendly_name());
|
||||
EXPECT_EQ(output0Name, expected1->output(0).get_node()->get_friendly_name());
|
||||
EXPECT_EQ(output1Name, expected1->output(1).get_node()->get_friendly_name());
|
||||
EXPECT_EQ(input0Name, expected2->input(0).get_node()->get_friendly_name());
|
||||
EXPECT_EQ(input1Name, expected2->input(1).get_node()->get_friendly_name());
|
||||
EXPECT_EQ(output0Name, expected2->output(0).get_node()->get_friendly_name());
|
||||
EXPECT_EQ(output1Name, expected2->output(1).get_node()->get_friendly_name());
|
||||
|
||||
std::ifstream xml_1(m_out_xml_path_1, std::ios::in | std::ios::binary);
|
||||
std::ifstream xml_2(m_out_xml_path_2, std::ios::in | std::ios::binary);
|
||||
EXPECT_TRUE(files_equal(xml_1, xml_2));
|
||||
}
|
||||
|
||||
TEST_P(SerializationDeterministicityInputOutputTest, FromIrModel) {
|
||||
auto irVersion = GetParam();
|
||||
|
||||
std::string irModel_1stPart = R"V0G0N(<?xml version="1.0"?>
|
||||
<net name="Model0" version=")V0G0N";
|
||||
std::string irModel_2ndPart = R"V0G0N(">
|
||||
<layers>
|
||||
<layer id="0" name="input0" type="Parameter" version="opset1">
|
||||
<data shape="1,3,22,22" element_type="f32" />
|
||||
<output>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="1" name="input1" type="Parameter" version="opset1">
|
||||
<data shape="1,3,22,22" element_type="f32" />
|
||||
<output>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="2" name="output0" type="Result" version="opset1">
|
||||
<input>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
<layer id="3" name="output1" type="Result" version="opset1">
|
||||
<input>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
</layers>
|
||||
<edges>
|
||||
<edge from-layer="0" from-port="0" to-layer="2" to-port="0" />
|
||||
<edge from-layer="1" from-port="0" to-layer="3" to-port="0" />
|
||||
</edges>
|
||||
<rt_info />
|
||||
</net>
|
||||
)V0G0N";
|
||||
std::string strVersion = irVersion == ov::pass::Serialize::Version::IR_V11 ? "11" : "10";
|
||||
std::string irModel = irModel_1stPart + strVersion + irModel_2ndPart;
|
||||
|
||||
{
|
||||
std::ofstream xmlFile;
|
||||
xmlFile.open(xmlFileName);
|
||||
xmlFile << irModel;
|
||||
xmlFile.close();
|
||||
}
|
||||
|
||||
auto expected1 = ov::test::readModel(xmlFileName, "");
|
||||
ov::pass::Serialize(m_out_xml_path_1, "", irVersion).run_on_model(expected1);
|
||||
auto expected2 = ov::test::readModel(m_out_xml_path_1, "");
|
||||
ov::pass::Serialize(m_out_xml_path_2, "", irVersion).run_on_model(expected2);
|
||||
|
||||
EXPECT_EQ(input0Name, expected1->input(0).get_node()->get_friendly_name());
|
||||
EXPECT_EQ(input1Name, expected1->input(1).get_node()->get_friendly_name());
|
||||
EXPECT_EQ(output0Name, expected1->output(0).get_node()->get_friendly_name());
|
||||
EXPECT_EQ(output1Name, expected1->output(1).get_node()->get_friendly_name());
|
||||
EXPECT_EQ(input0Name, expected2->input(0).get_node()->get_friendly_name());
|
||||
EXPECT_EQ(input1Name, expected2->input(1).get_node()->get_friendly_name());
|
||||
EXPECT_EQ(output0Name, expected2->output(0).get_node()->get_friendly_name());
|
||||
EXPECT_EQ(output1Name, expected2->output(1).get_node()->get_friendly_name());
|
||||
|
||||
std::ifstream xml_1(m_out_xml_path_1, std::ios::in | std::ios::binary);
|
||||
std::ifstream xml_2(m_out_xml_path_2, std::ios::in | std::ios::binary);
|
||||
EXPECT_TRUE(files_equal(xml_2, xml_1));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(DeterministicityInputOutput,
|
||||
SerializationDeterministicityInputOutputTest,
|
||||
::testing::Values(ov::pass::Serialize::Version::IR_V10, ov::pass::Serialize::Version::IR_V11));
|
||||
Loading…
Reference in New Issue