[PyOV] Deprecate PerformanceMode.UNDEFINED and refactor deprecation (#16965)

This commit is contained in:
Jan Iwaszkiewicz 2023-04-17 12:38:28 +02:00 committed by GitHub
parent 7c41d78b5d
commit 816c0f76e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 132 additions and 7 deletions

View File

@ -60,7 +60,7 @@ from openvino.runtime import opset10
from openvino.runtime import opset11
# Import properties API
from openvino._pyopenvino import properties
from openvino.runtime import properties
# Helper functions for openvino module
from openvino.runtime.ie_api import tensor_from_file

View File

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
# Enums
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
# Submodules
from openvino.runtime.properties import hint
from openvino._pyopenvino.properties import intel_cpu
from openvino._pyopenvino.properties import intel_gpu
from openvino._pyopenvino.properties import intel_auto
from openvino._pyopenvino.properties import device
from openvino._pyopenvino.properties import log
from openvino._pyopenvino.properties import streams

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
# Enums
from openvino._pyopenvino.properties.hint import Priority
from openvino._pyopenvino.properties.hint import SchedulingCoreType
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

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
from openvino.utils import deprecatedclassproperty
from openvino._pyopenvino.properties.hint import PerformanceMode as PerformanceModeBase
class PerformanceMode(PerformanceModeBase):
@deprecatedclassproperty(
name="PerformanceMode.UNDEFINED", # noqa: N802, N805
version="2024.0",
message="Please use actual value instead.",
stacklevel=2,
)
def UNDEFINED(cls) -> PerformanceModeBase: # noqa: N802, N805
return super().UNDEFINED

View File

@ -38,7 +38,7 @@ def add_openvino_libs_to_path() -> None:
os.environ["PATH"] = os.path.abspath(lib_path) + ";" + os.environ["PATH"]
def deprecated(version: str = "", message: str = "") -> Callable[..., Any]:
def deprecated(name: Any = None, version: str = "", message: str = "", stacklevel: int = 2) -> Callable[..., Any]:
"""Prints deprecation warning "{function_name} is deprecated and will be removed in version {version}. {message}" and runs the function.
:param version: The version in which the code will be removed.
@ -51,9 +51,48 @@ def deprecated(version: str = "", message: str = "") -> Callable[..., Any]:
# it must be imported here; otherwise, there are errors with no loaded DLL for Windows
from openvino._pyopenvino.util import deprecation_warning
deprecation_warning(wrapped.__name__, version, message)
deprecation_warning(wrapped.__name__ if name is None else name, version, message, stacklevel)
return wrapped(*args, **kwargs)
return wrapper
return decorator
# WA method since Python 3.11 does not support @classmethod and @property chain,
# currently only read-only properties are supported.
class _ClassPropertyDescriptor(object):
def __init__(self, fget: Callable):
self.fget = fget
def __get__(self, obj: Any, cls: Any = None) -> Any:
if cls is None:
cls = type(obj)
return self.fget.__get__(obj, cls)()
def classproperty(func: Any) -> _ClassPropertyDescriptor:
if not isinstance(func, (classmethod, staticmethod)):
func = classmethod(func)
return _ClassPropertyDescriptor(func)
def deprecatedclassproperty(name: Any = None, version: str = "", message: str = "", stacklevel: int = 2) -> Callable[[Any], _ClassPropertyDescriptor]:
def decorator(wrapped: Any) -> _ClassPropertyDescriptor:
func = classproperty(wrapped)
# Override specific instance
def _patch(instance: _ClassPropertyDescriptor, func: Callable[..., Any]) -> None:
cls_: Any = type(instance)
class _(cls_): # noqa: N801
@func
def __get__(self, obj: Any, cls: Any = None) -> Any:
return super().__get__(obj, cls)
instance.__class__ = _
# Add `deprecated` decorator on the top of `__get__`
_patch(func, deprecated(name, version, message, stacklevel))
return func
return decorator

View File

@ -79,17 +79,19 @@ void regmodule_graph_util(py::module m) {
mod.def(
"deprecation_warning",
[](const std::string& function_name, const std::string& version, const std::string& message) {
[](const std::string& function_name, const std::string& version, const std::string& message, int stacklevel) {
Common::utils::deprecation_warning(function_name, version, message);
},
py::arg("function_name"),
py::arg("version") = "",
py::arg("message") = "",
py::arg("stacklevel") = 2,
R"(
Prints deprecation warning "{function_name} is deprecated and will be removed in version {version}. {message}".
:param function_name: The name of the deprecated function.
:param version: The version in which the code will be removed.
:param message: A message explaining why the function is deprecated.
:param stacklevel: How many layers should be propagated.
)");
}

View File

@ -240,7 +240,10 @@ Version convert_to_version(const std::string& version) {
"'! The supported versions are: 'UNSPECIFIED'(default), 'IR_V10', 'IR_V11'.");
}
void deprecation_warning(const std::string& function_name, const std::string& version, const std::string& message) {
void deprecation_warning(const std::string& function_name,
const std::string& version,
const std::string& message,
int stacklevel) {
std::stringstream ss;
ss << function_name << " is deprecated";
if (!version.empty()) {
@ -249,7 +252,7 @@ void deprecation_warning(const std::string& function_name, const std::string& ve
if (!message.empty()) {
ss << ". " << message;
}
PyErr_WarnEx(PyExc_DeprecationWarning, ss.str().data(), 2);
PyErr_WarnEx(PyExc_DeprecationWarning, ss.str().data(), stacklevel);
}
bool py_object_is_any_map(const py::object& py_obj) {

View File

@ -40,7 +40,7 @@ namespace utils {
std::string convert_path_to_string(const py::object& path);
void deprecation_warning(const std::string& function_name, const std::string& version = std::string(), const std::string& message = std::string());
void deprecation_warning(const std::string& function_name, const std::string& version = std::string(), const std::string& message = std::string(), int stacklevel=2);
bool py_object_is_any_map(const py::object& py_obj);

View File

@ -27,6 +27,13 @@ def test_properties_rw_base():
assert "incompatible function arguments" in str(e.value)
def test_deprecation():
with pytest.warns(DeprecationWarning) as w:
_ = properties.hint.PerformanceMode.UNDEFINED
assert issubclass(w[0].category, DeprecationWarning)
assert "PerformanceMode.UNDEFINED is deprecated and will be removed" in str(w[0].message)
###
# Enum-like values
###