[PyOV] Make openvino properties behave as python property object (#20007)
* properties as property * working prototype * another attempt * fix for test * cosmetic changes * generate properties * test upste * add comments * update submodules * apply comments
This commit is contained in:
parent
2742752747
commit
9dfed28aed
@ -6,25 +6,9 @@
|
||||
from openvino._pyopenvino.properties import Affinity
|
||||
|
||||
# Properties
|
||||
from openvino._pyopenvino.properties import enable_profiling
|
||||
from openvino._pyopenvino.properties import cache_dir
|
||||
from openvino._pyopenvino.properties import auto_batch_timeout
|
||||
from openvino._pyopenvino.properties import num_streams
|
||||
from openvino._pyopenvino.properties import inference_num_threads
|
||||
from openvino._pyopenvino.properties import compilation_num_threads
|
||||
from openvino._pyopenvino.properties import affinity
|
||||
from openvino._pyopenvino.properties import force_tbb_terminate
|
||||
from openvino._pyopenvino.properties import enable_mmap
|
||||
from openvino._pyopenvino.properties import supported_properties
|
||||
from openvino._pyopenvino.properties import available_devices
|
||||
from openvino._pyopenvino.properties import model_name
|
||||
from openvino._pyopenvino.properties import optimal_number_of_infer_requests
|
||||
from openvino._pyopenvino.properties import range_for_streams
|
||||
from openvino._pyopenvino.properties import optimal_batch_size
|
||||
from openvino._pyopenvino.properties import max_batch_size
|
||||
from openvino._pyopenvino.properties import range_for_async_infer_requests
|
||||
from openvino._pyopenvino.properties import execution_devices
|
||||
from openvino._pyopenvino.properties import loaded_from_cache
|
||||
import openvino._pyopenvino.properties as __properties
|
||||
from openvino.properties._properties import __make_properties
|
||||
__make_properties(__properties, __name__)
|
||||
|
||||
# Submodules
|
||||
from openvino.runtime.properties import hint
|
||||
|
55
src/bindings/python/src/openvino/properties/_properties.py
Normal file
55
src/bindings/python/src/openvino/properties/_properties.py
Normal file
@ -0,0 +1,55 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2018-2023 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import sys
|
||||
from types import BuiltinFunctionType, ModuleType
|
||||
from typing import Callable, Any, Union
|
||||
|
||||
|
||||
class Property(str):
|
||||
"""This class allows to make a string object callable. Call returns underlying string's data."""
|
||||
def __new__(cls, prop: Callable[..., Any]): # type: ignore
|
||||
instance = super().__new__(cls, prop())
|
||||
instance.prop = prop
|
||||
return instance
|
||||
|
||||
def __call__(self, *args: Any) -> Callable[..., Any]:
|
||||
if args is not None:
|
||||
return self.prop(*args)
|
||||
return self.prop()
|
||||
|
||||
|
||||
def __append_property_to_module(func: Callable[..., Any], target_module_name: str) -> None:
|
||||
"""Modifies the target module's __getattr__ method to expose a python property wrapper by the function's name.
|
||||
|
||||
:param func: the function which will be transformed to behave as python property.
|
||||
:param target_module_name: the name of the module to which properties are added.
|
||||
"""
|
||||
module = sys.modules[target_module_name]
|
||||
|
||||
def base_getattr(name: str) -> None:
|
||||
raise AttributeError(
|
||||
f"Module '{module.__name__}' doesn't have the attribute with name '{name}'.")
|
||||
|
||||
getattr_old = getattr(module, "__getattr__", base_getattr)
|
||||
|
||||
def getattr_new(name: str) -> Union[Callable[..., Any], Any]:
|
||||
if func.__name__ == name:
|
||||
return Property(func)
|
||||
else:
|
||||
return getattr_old(name)
|
||||
|
||||
module.__getattr__ = getattr_new # type: ignore
|
||||
|
||||
|
||||
def __make_properties(source_module_of_properties: ModuleType, target_module_name: str) -> None:
|
||||
"""Makes python properties in target module from functions found in the source module.
|
||||
|
||||
:param source_module_of_properties: the source module from which functions should be taken.
|
||||
:param target_module_name: the name of the module to which properties are added.
|
||||
"""
|
||||
for attr in dir(source_module_of_properties):
|
||||
func = getattr(source_module_of_properties, attr)
|
||||
if isinstance(func, BuiltinFunctionType):
|
||||
__append_property_to_module(func, target_module_name)
|
@ -6,17 +6,9 @@
|
||||
from openvino._pyopenvino.properties.device import Type
|
||||
|
||||
# Properties
|
||||
from openvino._pyopenvino.properties.device import priorities
|
||||
from openvino._pyopenvino.properties.device import id
|
||||
from openvino._pyopenvino.properties.device import full_name
|
||||
from openvino._pyopenvino.properties.device import architecture
|
||||
from openvino._pyopenvino.properties.device import type
|
||||
from openvino._pyopenvino.properties.device import gops
|
||||
from openvino._pyopenvino.properties.device import thermal
|
||||
from openvino._pyopenvino.properties.device import capabilities
|
||||
from openvino._pyopenvino.properties.device import uuid
|
||||
from openvino._pyopenvino.properties.device import luid
|
||||
from openvino._pyopenvino.properties.device import properties
|
||||
import openvino._pyopenvino.properties.device as __device
|
||||
from openvino.properties._properties import __make_properties
|
||||
__make_properties(__device, __name__)
|
||||
|
||||
# Classes
|
||||
from openvino._pyopenvino.properties.device import Capability
|
||||
|
@ -9,13 +9,6 @@ from openvino._pyopenvino.properties.hint import ExecutionMode
|
||||
from openvino.runtime.properties.hint.overloads import PerformanceMode
|
||||
|
||||
# Properties
|
||||
from openvino._pyopenvino.properties.hint import inference_precision
|
||||
from openvino._pyopenvino.properties.hint import model_priority
|
||||
from openvino._pyopenvino.properties.hint import performance_mode
|
||||
from openvino._pyopenvino.properties.hint import enable_cpu_pinning
|
||||
from openvino._pyopenvino.properties.hint import scheduling_core_type
|
||||
from openvino._pyopenvino.properties.hint import enable_hyper_threading
|
||||
from openvino._pyopenvino.properties.hint import execution_mode
|
||||
from openvino._pyopenvino.properties.hint import num_requests
|
||||
from openvino._pyopenvino.properties.hint import model
|
||||
from openvino._pyopenvino.properties.hint import allow_auto_batching
|
||||
import openvino._pyopenvino.properties.hint as __hint
|
||||
from openvino.properties._properties import __make_properties
|
||||
__make_properties(__hint, __name__)
|
||||
|
@ -2,6 +2,7 @@
|
||||
# Copyright (C) 2018-2023 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
from openvino._pyopenvino.properties.intel_auto import device_bind_buffer
|
||||
from openvino._pyopenvino.properties.intel_auto import enable_startup_fallback
|
||||
from openvino._pyopenvino.properties.intel_auto import enable_runtime_fallback
|
||||
# Properties
|
||||
import openvino._pyopenvino.properties.intel_auto as __intel_auto
|
||||
from openvino.properties._properties import __make_properties
|
||||
__make_properties(__intel_auto, __name__)
|
||||
|
@ -2,5 +2,7 @@
|
||||
# Copyright (C) 2018-2023 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
from openvino._pyopenvino.properties.intel_cpu import denormals_optimization
|
||||
from openvino._pyopenvino.properties.intel_cpu import sparse_weights_decompression_rate
|
||||
# Properties
|
||||
import openvino._pyopenvino.properties.intel_cpu as __intel_cpu
|
||||
from openvino.properties._properties import __make_properties
|
||||
__make_properties(__intel_cpu, __name__)
|
||||
|
@ -3,12 +3,9 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Properties
|
||||
from openvino._pyopenvino.properties.intel_gpu import device_total_mem_size
|
||||
from openvino._pyopenvino.properties.intel_gpu import uarch_version
|
||||
from openvino._pyopenvino.properties.intel_gpu import execution_units_count
|
||||
from openvino._pyopenvino.properties.intel_gpu import memory_statistics
|
||||
from openvino._pyopenvino.properties.intel_gpu import enable_loop_unrolling
|
||||
from openvino._pyopenvino.properties.intel_gpu import disable_winograd_convolution
|
||||
import openvino._pyopenvino.properties.intel_gpu as __intel_gpu
|
||||
from openvino.properties._properties import __make_properties
|
||||
__make_properties(__intel_gpu, __name__)
|
||||
|
||||
# Classes
|
||||
from openvino._pyopenvino.properties.intel_gpu import MemoryType
|
||||
|
@ -3,10 +3,9 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Properties
|
||||
from openvino._pyopenvino.properties.intel_gpu.hint import queue_throttle
|
||||
from openvino._pyopenvino.properties.intel_gpu.hint import queue_priority
|
||||
from openvino._pyopenvino.properties.intel_gpu.hint import host_task_priority
|
||||
from openvino._pyopenvino.properties.intel_gpu.hint import available_device_mem
|
||||
import openvino._pyopenvino.properties.intel_gpu.hint as __hint
|
||||
from openvino.properties._properties import __make_properties
|
||||
__make_properties(__hint, __name__)
|
||||
|
||||
# Classes
|
||||
from openvino._pyopenvino.properties.intel_gpu.hint import ThrottleLevel
|
||||
|
@ -6,4 +6,6 @@
|
||||
from openvino._pyopenvino.properties.log import Level
|
||||
|
||||
# Properties
|
||||
from openvino._pyopenvino.properties.log import level
|
||||
import openvino._pyopenvino.properties.log as __log
|
||||
from openvino.properties._properties import __make_properties
|
||||
__make_properties(__log, __name__)
|
||||
|
@ -2,8 +2,10 @@
|
||||
# Copyright (C) 2018-2023 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Properties
|
||||
from openvino._pyopenvino.properties.streams import num
|
||||
|
||||
# Classes
|
||||
from openvino._pyopenvino.properties.streams import Num
|
||||
|
||||
# Properties
|
||||
import openvino._pyopenvino.properties.streams as __streams
|
||||
from openvino.properties._properties import __make_properties
|
||||
__make_properties(__streams, __name__)
|
||||
|
@ -1,11 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2022 Intel Corporation
|
||||
# Copyright (C) 2018-2023 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import pytest
|
||||
import numpy as np
|
||||
import os
|
||||
|
||||
import openvino as ov
|
||||
import openvino.properties as props
|
||||
import openvino.properties.hint as hints
|
||||
import openvino.properties.intel_cpu as intel_cpu
|
||||
@ -28,7 +29,7 @@ def test_properties_ro_base():
|
||||
|
||||
|
||||
def test_properties_rw_base():
|
||||
assert props.cache_dir() == "CACHE_DIR"
|
||||
assert ov.properties.cache_dir == "CACHE_DIR"
|
||||
assert props.cache_dir("./test_dir") == ("CACHE_DIR", OVAny("./test_dir"))
|
||||
|
||||
with pytest.raises(TypeError) as e:
|
||||
@ -181,6 +182,7 @@ def test_conflicting_enum(proxy_enums, expected_values):
|
||||
def test_properties_ro(ov_property_ro, expected_value):
|
||||
# Test if property is correctly registered
|
||||
assert ov_property_ro() == expected_value
|
||||
assert ov_property_ro == expected_value
|
||||
|
||||
|
||||
###
|
||||
@ -369,6 +371,7 @@ def test_properties_ro(ov_property_ro, expected_value):
|
||||
def test_properties_rw(ov_property_rw, expected_value, test_values):
|
||||
# Test if property is correctly registered
|
||||
assert ov_property_rw() == expected_value
|
||||
assert ov_property_rw == expected_value
|
||||
|
||||
# Test if property process values correctly
|
||||
for values in test_values:
|
||||
@ -381,7 +384,7 @@ def test_properties_rw(ov_property_rw, expected_value, test_values):
|
||||
# Special cases
|
||||
###
|
||||
def test_properties_device_priorities():
|
||||
assert device.priorities() == "MULTI_DEVICE_PRIORITIES"
|
||||
assert device.priorities == "MULTI_DEVICE_PRIORITIES"
|
||||
assert device.priorities("CPU,GPU") == ("MULTI_DEVICE_PRIORITIES", OVAny("CPU,GPU,"))
|
||||
assert device.priorities("CPU", "GPU") == ("MULTI_DEVICE_PRIORITIES", OVAny("CPU,GPU,"))
|
||||
|
||||
@ -401,7 +404,7 @@ def test_properties_device_properties():
|
||||
def check(value1, value2):
|
||||
assert device.properties(value1) == ("DEVICE_PROPERTIES", OVAny(value2))
|
||||
|
||||
check({"CPU": {streams.num(): 2}},
|
||||
check({"CPU": {streams.num: 2}},
|
||||
{"CPU": {"NUM_STREAMS": 2}})
|
||||
check({"CPU": make_dict(streams.num(2))},
|
||||
{"CPU": {"NUM_STREAMS": streams.Num(2)}})
|
||||
@ -457,7 +460,7 @@ def test_properties_hint_model():
|
||||
|
||||
model = generate_add_model()
|
||||
|
||||
assert hints.model() == "MODEL_PTR"
|
||||
assert hints.model == "MODEL_PTR"
|
||||
|
||||
property_tuple = hints.model(model)
|
||||
assert property_tuple[0] == "MODEL_PTR"
|
||||
@ -468,7 +471,7 @@ def test_single_property_setting(device):
|
||||
|
||||
core.set_property(device, streams.num(streams.Num.AUTO))
|
||||
|
||||
assert streams.Num.AUTO.to_integer() == -1
|
||||
assert props.streams.Num.AUTO.to_integer() == -1
|
||||
assert type(core.get_property(device, streams.num())) == int
|
||||
|
||||
|
||||
@ -494,28 +497,28 @@ def test_single_property_setting(device):
|
||||
),
|
||||
# Pure dict
|
||||
{
|
||||
props.enable_profiling(): True,
|
||||
props.cache_dir(): "./",
|
||||
props.inference_num_threads(): 9,
|
||||
props.affinity(): props.Affinity.NONE,
|
||||
hints.inference_precision(): Type.f32,
|
||||
hints.performance_mode(): hints.PerformanceMode.LATENCY,
|
||||
hints.enable_cpu_pinning(): True,
|
||||
hints.scheduling_core_type(): hints.SchedulingCoreType.PCORE_ONLY,
|
||||
hints.enable_hyper_threading(): True,
|
||||
hints.num_requests(): 12,
|
||||
streams.num(): 5,
|
||||
props.enable_profiling: True,
|
||||
props.cache_dir: "./",
|
||||
props.inference_num_threads: 9,
|
||||
props.affinity: props.Affinity.NONE,
|
||||
hints.inference_precision: Type.f32,
|
||||
hints.performance_mode: hints.PerformanceMode.LATENCY,
|
||||
hints.enable_cpu_pinning: True,
|
||||
hints.scheduling_core_type: hints.SchedulingCoreType.PCORE_ONLY,
|
||||
hints.enable_hyper_threading: True,
|
||||
hints.num_requests: 12,
|
||||
streams.num: 5,
|
||||
},
|
||||
# Mixed dict
|
||||
{
|
||||
props.enable_profiling(): True,
|
||||
props.enable_profiling: True,
|
||||
"CACHE_DIR": "./",
|
||||
props.inference_num_threads(): 9,
|
||||
props.affinity(): "NONE",
|
||||
props.inference_num_threads: 9,
|
||||
props.affinity: "NONE",
|
||||
"INFERENCE_PRECISION_HINT": Type.f32,
|
||||
hints.performance_mode(): hints.PerformanceMode.LATENCY,
|
||||
hints.scheduling_core_type(): hints.SchedulingCoreType.PCORE_ONLY,
|
||||
hints.num_requests(): 12,
|
||||
hints.performance_mode: hints.PerformanceMode.LATENCY,
|
||||
hints.scheduling_core_type: hints.SchedulingCoreType.PCORE_ONLY,
|
||||
hints.num_requests: 12,
|
||||
"NUM_STREAMS": streams.Num(5),
|
||||
"ENABLE_MMAP": "NO",
|
||||
},
|
||||
@ -526,21 +529,20 @@ def test_core_cpu_properties(properties_to_set):
|
||||
|
||||
if "Intel" not in core.get_property("CPU", "FULL_DEVICE_NAME"):
|
||||
pytest.skip("This test runs only on openvino intel cpu plugin")
|
||||
|
||||
core.set_property(properties_to_set)
|
||||
|
||||
# RW properties
|
||||
assert core.get_property("CPU", props.enable_profiling()) is True
|
||||
assert core.get_property("CPU", props.cache_dir()) == "./"
|
||||
assert core.get_property("CPU", props.inference_num_threads()) == 9
|
||||
assert core.get_property("CPU", props.affinity()) == props.Affinity.NONE
|
||||
assert core.get_property("CPU", streams.num()) == 5
|
||||
assert core.get_property("CPU", props.enable_profiling) is True
|
||||
assert core.get_property("CPU", props.cache_dir) == "./"
|
||||
assert core.get_property("CPU", props.inference_num_threads) == 9
|
||||
assert core.get_property("CPU", props.affinity) == props.Affinity.NONE
|
||||
assert core.get_property("CPU", streams.num) == 5
|
||||
|
||||
# RO properties
|
||||
assert type(core.get_property("CPU", props.supported_properties())) == dict
|
||||
assert type(core.get_property("CPU", props.available_devices())) == list
|
||||
assert type(core.get_property("CPU", props.optimal_number_of_infer_requests())) == int
|
||||
assert type(core.get_property("CPU", props.range_for_streams())) == tuple
|
||||
assert type(core.get_property("CPU", props.range_for_async_infer_requests())) == tuple
|
||||
assert type(core.get_property("CPU", device.full_name())) == str
|
||||
assert type(core.get_property("CPU", device.capabilities())) == list
|
||||
assert type(core.get_property("CPU", props.supported_properties)) == dict
|
||||
assert type(core.get_property("CPU", props.available_devices)) == list
|
||||
assert type(core.get_property("CPU", props.optimal_number_of_infer_requests)) == int
|
||||
assert type(core.get_property("CPU", props.range_for_streams)) == tuple
|
||||
assert type(core.get_property("CPU", props.range_for_async_infer_requests)) == tuple
|
||||
assert type(core.get_property("CPU", device.full_name)) == str
|
||||
assert type(core.get_property("CPU", device.capabilities)) == list
|
||||
|
Loading…
Reference in New Issue
Block a user