From c8720f122d502f21784db1a7cbe20ae7d3d52cfe Mon Sep 17 00:00:00 2001 From: Alexey Lebedev Date: Wed, 30 Mar 2022 19:43:07 +0300 Subject: [PATCH] [PYTHON API] lifetime test for CompiledModel and extension (#11120) * Add test for lifitime and extensions * Remove ExtendedModel --- .../python/src/openvino/runtime/ie_api.py | 14 ++--- src/bindings/python/tests/conftest.py | 58 ++++++++++++++++++ .../test_compiled_model.py | 11 +++- .../tests/test_inference_engine/test_core.py | 60 ++----------------- 4 files changed, 77 insertions(+), 66 deletions(-) diff --git a/src/bindings/python/src/openvino/runtime/ie_api.py b/src/bindings/python/src/openvino/runtime/ie_api.py index b8ec1b23866..a49f6f62ee5 100644 --- a/src/bindings/python/src/openvino/runtime/ie_api.py +++ b/src/bindings/python/src/openvino/runtime/ie_api.py @@ -334,23 +334,17 @@ class Core(CoreBase): ) -class ExtendedModel(CompiledModel): - """CompiledModel that additionally holds Core object.""" - - def __init__(self, core: Core, net: CompiledModel): - super().__init__(net) - self.core = core # needs to store Core object for CPU plugin - - def compile_model(model_path: str) -> CompiledModel: """Compact method to compile model with AUTO plugin. :param model_path: Path to file with model. :type model_path: str - :return: Extended version of `CompiledModel` that holds and keeps alive `Core` object. + :return: A compiled model. + :rtype: openvino.runtime.CompiledModel + """ core = Core() - return ExtendedModel(core, core.compile_model(model_path, "AUTO")) + return core.compile_model(model_path, "AUTO") class OVAny(OVAnyBase): diff --git a/src/bindings/python/tests/conftest.py b/src/bindings/python/tests/conftest.py index 3ba267affbd..8c527d9478d 100644 --- a/src/bindings/python/tests/conftest.py +++ b/src/bindings/python/tests/conftest.py @@ -8,6 +8,8 @@ import numpy as np import tests from pathlib import Path +from sys import platform +from openvino.runtime import Core def image_path(): @@ -29,6 +31,62 @@ def read_image(): return image +def get_model_with_template_extension(): + core = Core() + ir = bytes(b""" + + + + + + 1 + 3 + 22 + 22 + + + + + + + 1 + 3 + 22 + 22 + + + + + 1 + 3 + 22 + 22 + + + + + + + 1 + 3 + 22 + 22 + + + + + + + + +""") + if platform == "win32": + core.add_extension(library_path="openvino_template_extension.dll") + else: + core.add_extension(library_path="libopenvino_template_extension.so") + return core, core.read_model(ir) + + def model_path(is_myriad=False): path_to_repo = os.environ["MODELS_PATH"] if not is_myriad: diff --git a/src/bindings/python/tests/test_inference_engine/test_compiled_model.py b/src/bindings/python/tests/test_inference_engine/test_compiled_model.py index e0bb872bf4d..6b47b3dfc1a 100644 --- a/src/bindings/python/tests/test_inference_engine/test_compiled_model.py +++ b/src/bindings/python/tests/test_inference_engine/test_compiled_model.py @@ -5,7 +5,7 @@ import os import pytest import numpy as np -from ..conftest import model_path, read_image +from ..conftest import model_path, read_image, get_model_with_template_extension from openvino.runtime import Model, ConstOutput, Shape from openvino.runtime import Core, Tensor @@ -340,3 +340,12 @@ def test_direct_infer(device): assert np.argmax(res[comp_model.outputs[0]]) == 2 ref = comp_model.infer_new_request({"data": tensor}) assert np.array_equal(ref[comp_model.outputs[0]], res[comp_model.outputs[0]]) + + +def test_compiled_model_after_core_destroyed(device): + core, model = get_model_with_template_extension() + compiled = core.compile_model(model, device) + del core + del model + # check compiled and infer request can work properly after core object is destroyed + compiled([np.random.normal(size=list(input.shape)) for input in compiled.inputs]) diff --git a/src/bindings/python/tests/test_inference_engine/test_core.py b/src/bindings/python/tests/test_inference_engine/test_core.py index 6340e7c30c7..ac80e22e7b7 100644 --- a/src/bindings/python/tests/test_inference_engine/test_core.py +++ b/src/bindings/python/tests/test_inference_engine/test_core.py @@ -11,7 +11,8 @@ import openvino.runtime.opset8 as ov from openvino.runtime import Model, Core, CompiledModel, Tensor, PartialShape, Extension,\ tensor_from_file, compile_model -from ..conftest import model_path, model_onnx_path, plugins_path, read_image +from ..conftest import model_path, model_onnx_path, plugins_path, read_image, \ + get_model_with_template_extension test_net_xml, test_net_bin = model_path() @@ -254,60 +255,7 @@ def test_unregister_plugin(device): @pytest.mark.template_extension def test_add_extension_template_extension(device): - ir = bytes(b""" - - - - - - 1 - 3 - 22 - 22 - - - - - - - 1 - 3 - 22 - 22 - - - - - 1 - 3 - 22 - 22 - - - - - - - 1 - 3 - 22 - 22 - - - - - - - - -""") - - core = Core() - if platform == "win32": - core.add_extension(library_path="openvino_template_extension.dll") - else: - core.add_extension(library_path="libopenvino_template_extension.so") - model = core.read_model(model=ir) + core, model = get_model_with_template_extension() assert isinstance(model, Model) before_reshape = PartialShape([1, 3, 22, 22]) @@ -315,6 +263,8 @@ def test_add_extension_template_extension(device): new_shapes = {"in_data": after_reshape} assert model.input().partial_shape == before_reshape model.reshape(new_shapes) + # compile to check objects can be destroyed + # in order core -> model -> compiled compiled = core.compile_model(model, device) assert compiled.input().partial_shape == after_reshape