From 7a7675a778563063cd2224f2cdafc1a2b2f62fe0 Mon Sep 17 00:00:00 2001 From: Ilya Churaev Date: Fri, 9 Dec 2022 19:45:12 +0400 Subject: [PATCH] Added complex meta tests for C++ and python (#14265) * Added complex meta tests for C++ and python * Fixed python test * Fixed code style * Fixed python code style * Added any test --- .../python/src/pyopenvino/graph/model.cpp | 14 +++- .../python/src/pyopenvino/utils/utils.hpp | 4 + .../tests/test_runtime/test_function.py | 80 ++++++++++++++++++ src/core/src/any.cpp | 3 +- src/core/tests/any.cpp | 12 ++- src/core/tests/model.cpp | 68 +++++++++++++++ .../tests/pass/serialization/serialize.cpp | 82 +++++++++++++++++++ 7 files changed, 257 insertions(+), 6 deletions(-) diff --git a/src/bindings/python/src/pyopenvino/graph/model.cpp b/src/bindings/python/src/pyopenvino/graph/model.cpp index d99454fbf5d..d1907000398 100644 --- a/src/bindings/python/src/pyopenvino/graph/model.cpp +++ b/src/bindings/python/src/pyopenvino/graph/model.cpp @@ -752,11 +752,17 @@ void regclass_graph_Model(py::module m) { model.def( "has_rt_info", [](const ov::Model& self, const py::list& path) -> bool { - std::vector cpp_args(path.size()); - for (size_t i = 0; i < path.size(); i++) { - cpp_args[i] = path[i].cast(); + // FIXME: understand why has_rt_info causes Python crash + try { + std::vector cpp_args(path.size()); + for (size_t i = 0; i < path.size(); i++) { + cpp_args[i] = path[i].cast(); + } + self.get_rt_info(cpp_args); + return true; + } catch (ov::Exception&) { + return false; } - return self.has_rt_info(cpp_args); }, py::arg("path"), R"( diff --git a/src/bindings/python/src/pyopenvino/utils/utils.hpp b/src/bindings/python/src/pyopenvino/utils/utils.hpp index dc7034d311c..57d689c27bb 100644 --- a/src/bindings/python/src/pyopenvino/utils/utils.hpp +++ b/src/bindings/python/src/pyopenvino/utils/utils.hpp @@ -56,6 +56,10 @@ inline ov::Any py_object_to_any(const py::object& py_obj) { } } + // In case of empty vector works like with vector of strings + if (_list.empty()) + return _list.cast>(); + switch (detected_type) { case PY_TYPE::STR: return _list.cast>(); diff --git a/src/bindings/python/tests/test_runtime/test_function.py b/src/bindings/python/tests/test_runtime/test_function.py index 54aca1ca6f4..20932e1dc48 100644 --- a/src/bindings/python/tests/test_runtime/test_function.py +++ b/src/bindings/python/tests/test_runtime/test_function.py @@ -515,3 +515,83 @@ def test_serialize_rt_info(request): os.remove(xml_path) os.remove(bin_path) + + +# request - https://docs.pytest.org/en/7.1.x/reference/reference.html#request +def test_serialize_complex_rt_info(request): + def check_rt_info(model, serialized): + if serialized: + threshold = "13.23" + min_val = "-3.24543" + max_val = "3.23422" + directed = "YES" + empty = "" + ids = "sasd fdfdfsdf" + mean = "22.3 33.11 44" + else: + threshold = 13.23 + min_val = -3.24543 + max_val = 3.234223 + directed = True + empty = [] + ids = ["sasd", "fdfdfsdf"] + mean = [22.3, 33.11, 44.0] + assert model.has_rt_info(["config", "type_of_model"]) is True + assert model.has_rt_info(["config", "converter_type"]) is True + assert model.has_rt_info(["config", "model_parameters", "threshold"]) is True + assert model.has_rt_info(["config", "model_parameters", "min"]) is True + assert model.has_rt_info(["config", "model_parameters", "max"]) is True + assert model.has_rt_info(["config", "model_parameters", "labels", "label_tree", "type"]) is True + assert model.has_rt_info(["config", "model_parameters", "labels", "label_tree", "directed"]) is True + assert model.has_rt_info(["config", "model_parameters", "labels", "label_tree", "float_empty"]) is True + assert model.has_rt_info(["config", "model_parameters", "labels", "label_tree", "nodes"]) is True + assert model.has_rt_info(["config", "model_parameters", "labels", "label_groups", "ids"]) is True + assert model.has_rt_info(["config", "model_parameters", "mean_values"]) is True + + assert model.get_rt_info(["config", "type_of_model"]) == "classification" + assert model.get_rt_info(["config", "converter_type"]) == "classification" + assert model.get_rt_info(["config", "model_parameters", "threshold"]) == threshold + assert model.get_rt_info(["config", "model_parameters", "min"]) == min_val + assert model.get_rt_info(["config", "model_parameters", "max"]) == max_val + assert model.get_rt_info(["config", "model_parameters", "labels", "label_tree", "type"]) == "tree" + assert model.get_rt_info(["config", "model_parameters", "labels", "label_tree", "directed"]) == directed + assert model.get_rt_info(["config", "model_parameters", "labels", "label_tree", "float_empty"]) == empty + assert model.get_rt_info(["config", "model_parameters", "labels", "label_tree", "nodes"]) == empty + assert model.get_rt_info(["config", "model_parameters", "labels", "label_groups", "ids"]) == ids + assert model.get_rt_info(["config", "model_parameters", "mean_values"]) == mean + + core = Core() + xml_path, bin_path = create_filename_for_test(request.node.name) + input_shape = PartialShape([1]) + param = ops.parameter(input_shape, dtype=np.float32, name="data") + relu1 = ops.relu(param, name="relu1") + relu1.get_output_tensor(0).set_names({"relu_t1"}) + assert "relu_t1" in relu1.get_output_tensor(0).names + relu2 = ops.relu(relu1, name="relu2") + model = Model(relu2, [param], "TestFunction") + + assert model is not None + + model.set_rt_info("classification", ["config", "type_of_model"]) + model.set_rt_info("classification", ["config", "converter_type"]) + model.set_rt_info(13.23, ["config", "model_parameters", "threshold"]) + model.set_rt_info(-3.24543, ["config", "model_parameters", "min"]) + model.set_rt_info(3.234223, ["config", "model_parameters", "max"]) + model.set_rt_info("tree", ["config", "model_parameters", "labels", "label_tree", "type"]) + model.set_rt_info(True, ["config", "model_parameters", "labels", "label_tree", "directed"]) + model.set_rt_info([], ["config", "model_parameters", "labels", "label_tree", "float_empty"]) + model.set_rt_info([], ["config", "model_parameters", "labels", "label_tree", "nodes"]) + model.set_rt_info(["sasd", "fdfdfsdf"], ["config", "model_parameters", "labels", "label_groups", "ids"]) + model.set_rt_info([22.3, 33.11, 44.0], ["config", "model_parameters", "mean_values"]) + + check_rt_info(model, False) + + serialize(model, xml_path, bin_path) + + res_model = core.read_model(model=xml_path, weights=bin_path) + + check_rt_info(res_model, True) + + os.remove(xml_path) + os.remove(bin_path) + serialize(res_model, xml_path, bin_path) diff --git a/src/core/src/any.cpp b/src/core/src/any.cpp index aa37007f329..3891fe4c89b 100644 --- a/src/core/src/any.cpp +++ b/src/core/src/any.cpp @@ -63,7 +63,8 @@ void Any::Base::read_to(Base& other) const { if (other.is()) { *static_cast(other.addressof()) = strm.str(); } else { - other.read(strm); + if (!strm.str().empty()) + other.read(strm); } } diff --git a/src/core/tests/any.cpp b/src/core/tests/any.cpp index d2d562dabcf..0f00b4193fc 100644 --- a/src/core/tests/any.cpp +++ b/src/core/tests/any.cpp @@ -539,4 +539,14 @@ TEST_F(AnyTests, AddressofNoThrow) { ASSERT_EQ(nullptr, p.addressof()); p = 42; ASSERT_NE(nullptr, p.addressof()); -} \ No newline at end of file +} + +TEST_F(AnyTests, EmptyStringAsAny) { + Any p = ""; + std::vector ref_f; + std::vector ref_i; + ASSERT_TRUE(p.is()); + ASSERT_EQ(p.as(), 0); + ASSERT_EQ(p.as>(), ref_f); + ASSERT_EQ(p.as>(), ref_i); +} diff --git a/src/core/tests/model.cpp b/src/core/tests/model.cpp index 853584c58ad..3efcf326a61 100644 --- a/src/core/tests/model.cpp +++ b/src/core/tests/model.cpp @@ -6,6 +6,7 @@ #include +#include #include #include @@ -1972,3 +1973,70 @@ TEST(model, set_meta_information) { EXPECT_EQ(f->get_rt_info({key, "test1"}), "1"); EXPECT_EQ(f->get_rt_info({key, "test1"}), 1); } + +TEST(model, set_complex_meta_information) { + auto arg0 = std::make_shared(ov::element::f32, ov::PartialShape{1}); + arg0->set_friendly_name("data"); + arg0->get_output_tensor(0).set_names({"input"}); + + auto relu = std::make_shared(arg0); + relu->set_friendly_name("relu"); + relu->get_output_tensor(0).set_names({"relu_t", "identity"}); + auto f = std::make_shared(relu, ov::ParameterVector{arg0}); + + const auto check_rt_info = [](const std::shared_ptr& model) { + EXPECT_TRUE(model->has_rt_info("config", "type_of_model")); + EXPECT_TRUE(model->has_rt_info("config", "converter_type")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "threshold")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "min")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "max")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "labels", "label_tree", "type")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "labels", "label_tree", "directed")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "labels", "label_tree", "nodes")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "labels", "label_groups", "ids")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "mean_values")); + + EXPECT_EQ("classification", model->get_rt_info("config", "type_of_model")); + EXPECT_EQ("classification", model->get_rt_info("config", "converter_type")); + EXPECT_FLOAT_EQ(13.23f, model->get_rt_info("config", "model_parameters", "threshold")); + EXPECT_FLOAT_EQ(-3.245433f, model->get_rt_info("config", "model_parameters", "min")); + EXPECT_FLOAT_EQ(3.2342233f, model->get_rt_info("config", "model_parameters", "max")); + EXPECT_EQ("tree", + model->get_rt_info("config", "model_parameters", "labels", "label_tree", "type")); + EXPECT_EQ(true, model->get_rt_info("config", "model_parameters", "labels", "label_tree", "directed")); + EXPECT_EQ(std::vector{}, + model->get_rt_info>("config", + "model_parameters", + "labels", + "label_tree", + "nodes")); + std::vector str_vec{"sasd", "fdfdfsdf"}; + EXPECT_EQ(str_vec, + model->get_rt_info>("config", + "model_parameters", + "labels", + "label_groups", + "ids")); + std::vector fl_vec{22.3f, 33.11f, 44.f}; + EXPECT_EQ(fl_vec, model->get_rt_info>("config", "model_parameters", "mean_values")); + }; + + // Fill meta data + f->set_rt_info("classification", "config", "type_of_model"); + f->set_rt_info("classification", "config", "converter_type"); + f->set_rt_info(13.23f, "config", "model_parameters", "threshold"); + f->set_rt_info(-3.245433f, "config", "model_parameters", "min"); + f->set_rt_info(3.2342233f, "config", "model_parameters", "max"); + f->set_rt_info("tree", "config", "model_parameters", "labels", "label_tree", "type"); + f->set_rt_info(true, "config", "model_parameters", "labels", "label_tree", "directed"); + f->set_rt_info(std::vector{}, "config", "model_parameters", "labels", "label_tree", "nodes"); + f->set_rt_info(std::vector{"sasd", "fdfdfsdf"}, + "config", + "model_parameters", + "labels", + "label_groups", + "ids"); + f->set_rt_info(std::vector{22.3f, 33.11f, 44.f}, "config", "model_parameters", "mean_values"); + + check_rt_info(f); +} diff --git a/src/core/tests/pass/serialization/serialize.cpp b/src/core/tests/pass/serialization/serialize.cpp index ae9d3c50801..594d0e0b294 100644 --- a/src/core/tests/pass/serialization/serialize.cpp +++ b/src/core/tests/pass/serialization/serialize.cpp @@ -406,3 +406,85 @@ TEST_F(MetaDataSerialize, get_meta_serialized_changed_meta) { check_meta_info(s_model); } } + +TEST_F(MetaDataSerialize, set_complex_meta_information) { + const auto check_rt_info = [](const std::shared_ptr& model) { + EXPECT_TRUE(model->has_rt_info("config", "type_of_model")); + EXPECT_TRUE(model->has_rt_info("config", "converter_type")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "threshold")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "min")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "max")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "labels", "label_tree", "type")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "labels", "label_tree", "directed")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "labels", "label_tree", "nodes")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "labels", "label_tree", "float_empty")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "labels", "label_groups", "ids")); + EXPECT_TRUE(model->has_rt_info("config", "model_parameters", "mean_values")); + + EXPECT_EQ("classification", model->get_rt_info("config", "type_of_model")); + EXPECT_EQ("classification", model->get_rt_info("config", "converter_type")); + EXPECT_GE(0.0001f, model->get_rt_info("config", "model_parameters", "threshold") - 13.23f); + EXPECT_GE(0.0001f, model->get_rt_info("config", "model_parameters", "min") - (-3.245433f)); + EXPECT_GE(0.0001f, model->get_rt_info("config", "model_parameters", "max") - 3.2342233f); + EXPECT_EQ("tree", + model->get_rt_info("config", "model_parameters", "labels", "label_tree", "type")); + EXPECT_EQ(true, model->get_rt_info("config", "model_parameters", "labels", "label_tree", "directed")); + EXPECT_EQ(std::vector{}, + model->get_rt_info>("config", + "model_parameters", + "labels", + "label_tree", + "nodes")); + EXPECT_EQ(std::vector{}, + model->get_rt_info>("config", + "model_parameters", + "labels", + "label_tree", + "float_empty")); + std::vector str_vec{"sasd", "fdfdfsdf"}; + EXPECT_EQ(str_vec, + model->get_rt_info>("config", + "model_parameters", + "labels", + "label_groups", + "ids")); + std::vector fl_vec{22.3f, 33.11f, 44.f}; + EXPECT_EQ(fl_vec, model->get_rt_info>("config", "model_parameters", "mean_values")); + }; + + auto model = ov::test::readModel(ir_with_meta); + + { + auto& rt_info = model->get_rt_info(); + ASSERT_FALSE(rt_info.empty()); + check_meta_info(model); + // Fill meta data + model->set_rt_info("classification", "config", "type_of_model"); + model->set_rt_info("classification", "config", "converter_type"); + model->set_rt_info(13.23f, "config", "model_parameters", "threshold"); + model->set_rt_info(-3.245433f, "config", "model_parameters", "min"); + model->set_rt_info(3.2342233f, "config", "model_parameters", "max"); + model->set_rt_info("tree", "config", "model_parameters", "labels", "label_tree", "type"); + model->set_rt_info(true, "config", "model_parameters", "labels", "label_tree", "directed"); + model->set_rt_info(std::vector{}, "config", "model_parameters", "labels", "label_tree", "float_empty"); + model->set_rt_info(std::vector{}, "config", "model_parameters", "labels", "label_tree", "nodes"); + model->set_rt_info(std::vector{"sasd", "fdfdfsdf"}, + "config", + "model_parameters", + "labels", + "label_groups", + "ids"); + model->set_rt_info(std::vector{22.3f, 33.11f, 44.f}, "config", "model_parameters", "mean_values"); + + check_rt_info(model); + } + + // Serialize the model + ov::serialize(model, m_out_xml_path, m_out_bin_path); + + auto s_model = ov::test::readModel(m_out_xml_path, m_out_bin_path); + { + check_meta_info(s_model); + check_rt_info(s_model); + } +}