[PyOV] OVDict as input for infer/call methods (#21275)

* [PyOV] OVDict as input for infer/call methods

* for copied inputs

* improvement

* add test

* apply comments

* add test assert

---------

Co-authored-by: Michal Lukaszewski <michal.lukaszewski@intel.com>
This commit is contained in:
Anastasia Kuporosova 2023-12-13 19:13:18 +01:00 committed by GitHub
parent 4752237871
commit 1aa0c0ca0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 19 deletions

View File

@ -8,7 +8,7 @@ from typing import Any, Dict, Union, Optional
import numpy as np import numpy as np
from openvino._pyopenvino import ConstOutput, Tensor, Type from openvino._pyopenvino import ConstOutput, Tensor, Type
from openvino.runtime.utils.data_helpers.wrappers import _InferRequestWrapper from openvino.runtime.utils.data_helpers.wrappers import _InferRequestWrapper, OVDict
ContainerTypes = Union[dict, list, tuple] ContainerTypes = Union[dict, list, tuple]
ScalarTypes = Union[np.number, int, float] ScalarTypes = Union[np.number, int, float]
@ -132,6 +132,14 @@ def _(
return {k: to_c_style(v) if is_shared else v for k, v in inputs.items()} return {k: to_c_style(v) if is_shared else v for k, v in inputs.items()}
@normalize_arrays.register(OVDict)
def _(
inputs: OVDict,
is_shared: bool = False,
) -> dict:
return {i: to_c_style(v) if is_shared else v for i, (_, v) in enumerate(inputs.items())}
@normalize_arrays.register(list) @normalize_arrays.register(list)
@normalize_arrays.register(tuple) @normalize_arrays.register(tuple)
def _( def _(
@ -174,6 +182,7 @@ def create_shared(
@create_shared.register(dict) @create_shared.register(dict)
@create_shared.register(list) @create_shared.register(list)
@create_shared.register(tuple) @create_shared.register(tuple)
@create_shared.register(OVDict)
def _( def _(
inputs: ContainerTypes, inputs: ContainerTypes,
request: _InferRequestWrapper, request: _InferRequestWrapper,
@ -300,7 +309,7 @@ def update_inputs(inputs: dict, request: _InferRequestWrapper) -> dict:
@singledispatch @singledispatch
def create_copied( def create_copied(
inputs: Union[ContainerTypes, np.ndarray, ScalarTypes], inputs: Union[ContainerTypes, OVDict, np.ndarray, ScalarTypes],
request: _InferRequestWrapper, request: _InferRequestWrapper,
) -> Union[dict, None]: ) -> Union[dict, None]:
# Check the special case of the array-interface # Check the special case of the array-interface
@ -314,8 +323,9 @@ def create_copied(
@create_copied.register(dict) @create_copied.register(dict)
@create_copied.register(list) @create_copied.register(list)
@create_copied.register(tuple) @create_copied.register(tuple)
@create_copied.register(OVDict)
def _( def _(
inputs: ContainerTypes, inputs: Union[ContainerTypes, OVDict],
request: _InferRequestWrapper, request: _InferRequestWrapper,
) -> dict: ) -> dict:
return update_inputs(normalize_arrays(inputs, is_shared=False), request) return update_inputs(normalize_arrays(inputs, is_shared=False), request)
@ -346,7 +356,7 @@ def _(
def _data_dispatch( def _data_dispatch(
request: _InferRequestWrapper, request: _InferRequestWrapper,
inputs: Union[ContainerTypes, Tensor, np.ndarray, ScalarTypes] = None, inputs: Union[ContainerTypes, OVDict, Tensor, np.ndarray, ScalarTypes] = None,
is_shared: bool = False, is_shared: bool = False,
) -> Union[dict, Tensor]: ) -> Union[dict, Tensor]:
if inputs is None: if inputs is None:

View File

@ -4,13 +4,7 @@
import numpy as np import numpy as np
# TODO: remove this WA and refactor OVDict when Python3.8
# becomes minimal supported version.
try:
from functools import singledispatchmethod from functools import singledispatchmethod
except ImportError:
from singledispatchmethod import singledispatchmethod # type: ignore[no-redef]
from collections.abc import Mapping from collections.abc import Mapping
from typing import Dict, Set, Tuple, Union, Iterator, Optional from typing import Dict, Set, Tuple, Union, Iterator, Optional
from typing import KeysView, ItemsView, ValuesView from typing import KeysView, ItemsView, ValuesView

View File

@ -17,9 +17,6 @@ from openvino import (
Type, Type,
Tensor, Tensor,
) )
from openvino.runtime import ProfilingInfo
from openvino.preprocess import PrePostProcessor
from tests import skip_need_mock_op from tests import skip_need_mock_op
from tests.utils.helpers import generate_image, get_relu_model, generate_model_with_memory from tests.utils.helpers import generate_image, get_relu_model, generate_model_with_memory

View File

@ -2,7 +2,7 @@
# Copyright (C) 2018-2023 Intel Corporation # Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
from collections.abc import Iterable from contextlib import nullcontext as does_not_raise
from copy import deepcopy from copy import deepcopy
import numpy as np import numpy as np
import os import os
@ -14,18 +14,17 @@ import openvino.runtime.opset13 as ops
from openvino import ( from openvino import (
Core, Core,
CompiledModel, CompiledModel,
InferRequest,
Model, Model,
Layout, Layout,
PartialShape, PartialShape,
Shape, Shape,
Type, Type,
Tensor, Tensor,
compile_model,
) )
from openvino.runtime import ProfilingInfo from openvino.runtime import ProfilingInfo
from openvino.preprocess import PrePostProcessor from openvino.preprocess import PrePostProcessor
from tests import skip_need_mock_op
from tests.utils.helpers import generate_image, get_relu_model, generate_model_with_memory from tests.utils.helpers import generate_image, get_relu_model, generate_model_with_memory
@ -990,3 +989,35 @@ def test_infer_request_share_memory(device, share_inputs, share_outputs, is_posi
else: else:
assert not out_tensor_shares assert not out_tensor_shares
assert results[0].flags["OWNDATA"] is True assert results[0].flags["OWNDATA"] is True
def test_output_result_to_input():
def create_model_1():
param1 = ops.parameter(Shape([1, 1]), Type.i32)
param1.set_friendly_name("input_1")
add = ops.add(param1, ops.constant([1], Type.i32))
add1 = ops.add(param1, ops.constant([[5]], Type.i32))
model = Model([add, add1], [param1])
model.output(0).tensor.set_names({"output_1_1"})
model.output(1).tensor.set_names({"outputs_1_2"})
return model
def create_model_2():
param1 = ops.parameter(Shape([1, 1]), Type.i32)
param1.set_friendly_name("output_1_1")
param2 = ops.parameter(Shape([1, 1]), Type.i32)
param2.set_friendly_name("outputs_1_2")
add = ops.add(param1, param2)
model = Model([add], [param1, param2])
model.output(0).tensor.set_names({"output_2_1"})
return model
model_1 = create_model_1()
model_2 = create_model_2()
compiled_1, compiled_2 = compile_model(model_1), compile_model(model_2)
input_data = np.array([[1]])
result_1 = compiled_1(input_data, share_inputs=False)
with does_not_raise():
result_2 = compiled_2(result_1, share_inputs=False)
assert np.array_equal(result_2[0], [[8]])

View File

@ -7,8 +7,8 @@ import pytest
import numpy as np import numpy as np
from tests.utils.helpers import generate_relu_compiled_model from tests.utils.helpers import generate_relu_compiled_model
from openvino import Model, Type, Shape, Core, Tensor
from openvino.runtime import ConstOutput from openvino import Type, Shape, Tensor
from openvino.runtime.utils.data_helpers import _data_dispatch from openvino.runtime.utils.data_helpers import _data_dispatch
is_myriad = os.environ.get("TEST_DEVICE") == "MYRIAD" is_myriad = os.environ.get("TEST_DEVICE") == "MYRIAD"