Python Api, Variant -> OVAny (#9084)

This commit is contained in:
Artur Kulikowski
2021-12-10 11:32:25 +01:00
committed by GitHub
parent 3f96a1bccd
commit d6c2cb5238
10 changed files with 101 additions and 98 deletions

View File

@@ -65,7 +65,7 @@ from openvino.runtime.ie_api import Core
from openvino.runtime.ie_api import ExecutableNetwork
from openvino.runtime.ie_api import InferRequest
from openvino.runtime.ie_api import AsyncInferQueue
from openvino.runtime.ie_api import Variant
from openvino.runtime.ie_api import OVAny
from openvino.pyopenvino import Version
from openvino.pyopenvino import Parameter
from openvino.pyopenvino import Tensor

View File

@@ -12,7 +12,7 @@ from openvino.pyopenvino import InferRequest as InferRequestBase
from openvino.pyopenvino import AsyncInferQueue as AsyncInferQueueBase
from openvino.pyopenvino import Output
from openvino.pyopenvino import Tensor
from openvino.pyopenvino import Variant as VariantBase
from openvino.pyopenvino import OVAny as OVAnyBase
from openvino.runtime.utils.types import get_dtype
@@ -57,7 +57,9 @@ class InferRequest(InferRequestBase):
def infer(self, inputs: dict = None) -> dict:
"""Infer wrapper for InferRequest."""
inputs = {} if inputs is None else normalize_inputs(inputs, get_input_types(self))
inputs = (
{} if inputs is None else normalize_inputs(inputs, get_input_types(self))
)
return super().infer(inputs)
def start_async(self, inputs: dict = None, userdata: Any = None) -> None:
@@ -77,7 +79,9 @@ class ExecutableNetwork(ExecutableNetworkBase):
def infer_new_request(self, inputs: dict = None) -> dict:
"""Infer wrapper for ExecutableNetwork."""
inputs = {} if inputs is None else normalize_inputs(inputs, get_input_types(self))
inputs = (
{} if inputs is None else normalize_inputs(inputs, get_input_types(self))
)
return super().infer_new_request(inputs)
@@ -136,21 +140,21 @@ def compile_model(model_path: str) -> ExecutableNetwork:
return ExtendedNetwork(core, core.compile_model(model_path, "AUTO"))
class Variant(VariantBase):
"""Variant wrapper.
class OVAny(OVAnyBase):
"""OVAny wrapper.
Wrapper provides some useful overloads for simple built-in Python types.
Access to the Variant value is direct if it is a built-in Python data type.
Access to the OVAny value is direct if it is a built-in Python data type.
Example:
@code{.py}
variant = Variant([1, 2])
print(variant[0])
any = OVAny([1, 2])
print(any[0])
Output: 2
@endcode
Otherwise if Variant value is a custom data type (for example user class),
Otherwise if OVAny value is a custom data type (for example user class),
access to the value is possible by 'get()' method or property 'value'.
Example:
@code{.py}
@@ -158,8 +162,8 @@ class Variant(VariantBase):
def __init__(self):
self.data = "test"
v = Variant(Test())
print(v.value.data)
any = OVAny(Test())
print(any.value.data)
@endcode
"""

View File

@@ -4,59 +4,58 @@
#pragma once
#include <string>
#include <pybind11/stl.h>
#include <pybind11/numpy.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <ie_plugin_config.hpp>
#include <ie_parameter.hpp>
#include <ie_plugin_config.hpp>
#include <openvino/core/type/element_type.hpp>
#include <string>
#include "Python.h"
#include "ie_common.h"
#include "openvino/runtime/tensor.hpp"
#include "openvino/runtime/executable_network.hpp"
#include "openvino/runtime/infer_request.hpp"
#include "openvino/runtime/tensor.hpp"
#include "pyopenvino/core/containers.hpp"
#include "pyopenvino/graph/variant.hpp"
#include "pyopenvino/graph/any.hpp"
namespace py = pybind11;
namespace Common
{
const std::map<ov::element::Type, py::dtype>& ov_type_to_dtype();
namespace Common {
const std::map<ov::element::Type, py::dtype>& ov_type_to_dtype();
const std::map<py::str, ov::element::Type>& dtype_to_ov_type();
const std::map<py::str, ov::element::Type>& dtype_to_ov_type();
ov::runtime::Tensor tensor_from_numpy(py::array& array, bool shared_memory);
ov::runtime::Tensor tensor_from_numpy(py::array& array, bool shared_memory);
py::array as_contiguous(py::array& array, ov::element::Type type);
py::array as_contiguous(py::array& array, ov::element::Type type);
const ov::runtime::Tensor& cast_to_tensor(const py::handle& tensor);
const ov::runtime::Tensor& cast_to_tensor(const py::handle& tensor);
const Containers::TensorNameMap cast_to_tensor_name_map(const py::dict& inputs);
const Containers::TensorNameMap cast_to_tensor_name_map(const py::dict& inputs);
const Containers::TensorIndexMap cast_to_tensor_index_map(const py::dict& inputs);
const Containers::TensorIndexMap cast_to_tensor_index_map(const py::dict& inputs);
void set_request_tensors(ov::runtime::InferRequest& request, const py::dict& inputs);
void set_request_tensors(ov::runtime::InferRequest& request, const py::dict& inputs);
PyAny from_ov_any(const ov::Any& any);
PyAny from_ov_any(const ov::Any& any);
uint32_t get_optimal_number_of_requests(const ov::runtime::ExecutableNetwork& actual);
uint32_t get_optimal_number_of_requests(const ov::runtime::ExecutableNetwork& actual);
py::dict outputs_to_dict(const std::vector<ov::Output<const ov::Node>>& outputs, ov::runtime::InferRequest& request);
py::dict outputs_to_dict(const std::vector<ov::Output<const ov::Node>>& outputs, ov::runtime::InferRequest& request);
// Use only with classes that are not creatable by users on Python's side, because
// Objects created in Python that are wrapped with such wrapper will cause memory leaks.
template <typename T>
class ref_wrapper {
std::reference_wrapper<T> impl;
// Use only with classes that are not creatable by users on Python's side, because
// Objects created in Python that are wrapped with such wrapper will cause memory leaks.
template <typename T>
class ref_wrapper {
std::reference_wrapper<T> impl;
public:
explicit ref_wrapper(T* p) : impl(*p) {}
T* get() const {
return &impl.get();
public:
explicit ref_wrapper(T* p) : impl(*p) {}
T* get() const {
return &impl.get();
}
};
}; // namespace Common
}; // namespace Common

View File

@@ -2,35 +2,35 @@
// SPDX-License-Identifier: Apache-2.0
//
#include "pyopenvino/graph/variant.hpp"
#include "openvino/core/any.hpp"
#include <pybind11/pybind11.h>
#include "openvino/core/any.hpp"
#include "pyopenvino/core/common.hpp"
#include "pyopenvino/graph/any.hpp"
namespace py = pybind11;
void regclass_graph_Variant(py::module m) {
py::class_<PyAny, std::shared_ptr<PyAny>> variant(m, "Variant", py::module_local());
variant.doc() = "openvino.runtime.Variant wraps ov::Any";
variant.def(py::init<py::object>());
void regclass_graph_Any(py::module m) {
py::class_<PyAny, std::shared_ptr<PyAny>> ov_any(m, "OVAny", py::module_local());
ov_any.doc() = "openvino.runtime.OVAny wraps ov::Any";
ov_any.def(py::init<py::object>());
variant.def("__repr__", [](const PyAny& self) {
ov_any.def("__repr__", [](const PyAny& self) {
std::stringstream ret;
self.print(ret);
return ret.str();
});
variant.def("__eq__", [](const PyAny& a, const PyAny& b) -> bool {
ov_any.def("__eq__", [](const PyAny& a, const PyAny& b) -> bool {
return a == b;
});
variant.def("__eq__", [](const PyAny& a, const ov::Any& b) -> bool {
ov_any.def("__eq__", [](const PyAny& a, const ov::Any& b) -> bool {
return a == b;
});
variant.def("__eq__", [](const PyAny& a, py::object b) -> bool {
ov_any.def("__eq__", [](const PyAny& a, py::object b) -> bool {
return a == PyAny(b);
});
variant.def(
ov_any.def(
"get",
[](const PyAny& self) -> py::object {
return self.as<py::object>();
@@ -41,7 +41,7 @@ void regclass_graph_Variant(py::module m) {
get : Any
Value of ov::Any.
)");
variant.def(
ov_any.def(
"set",
[](PyAny& self, py::object value) {
self = PyAny(value);
@@ -53,7 +53,7 @@ void regclass_graph_Variant(py::module m) {
Value to be set in ov::Any.
)");
variant.def_property_readonly("value", [](const PyAny& self) {
ov_any.def_property_readonly("value", [](const PyAny& self) {
return self.as<py::object>();
});
}

View File

@@ -10,11 +10,11 @@
#include <string>
#include "Python.h"
#include "openvino/core/any.hpp" // ov::RuntimeAttribute
#include "openvino/core/any.hpp" // ov::RuntimeAttribute
namespace py = pybind11;
void regclass_graph_Variant(py::module m);
void regclass_graph_Any(py::module m);
class PyAny : public ov::Any {
public:

View File

@@ -14,9 +14,9 @@
#include "openvino/op/divide.hpp"
#include "openvino/op/multiply.hpp"
#include "openvino/op/subtract.hpp"
#include "pyopenvino/graph/any.hpp"
#include "pyopenvino/graph/node.hpp"
#include "pyopenvino/graph/rt_map.hpp"
#include "pyopenvino/graph/variant.hpp"
class PyNode : public ov::Node {
public:

View File

@@ -16,8 +16,8 @@
#include "openvino/op/multiply.hpp"
#include "openvino/op/subtract.hpp"
#include "pyopenvino/core/common.hpp"
#include "pyopenvino/graph/any.hpp"
#include "pyopenvino/graph/node.hpp"
#include "pyopenvino/graph/variant.hpp"
namespace py = pybind11;

View File

@@ -35,6 +35,7 @@
#include "pyopenvino/frontend/frontend_manager.hpp"
#include "pyopenvino/frontend/inputmodel.hpp"
#include "pyopenvino/frontend/place.hpp"
#include "pyopenvino/graph/any.hpp"
#include "pyopenvino/graph/descriptors/tensor.hpp"
#include "pyopenvino/graph/dimension.hpp"
#include "pyopenvino/graph/layout.hpp"
@@ -51,7 +52,6 @@
#include "pyopenvino/graph/strides.hpp"
#include "pyopenvino/graph/types/regmodule_graph_types.hpp"
#include "pyopenvino/graph/util.hpp"
#include "pyopenvino/graph/variant.hpp"
namespace py = pybind11;
@@ -107,7 +107,7 @@ PYBIND11_MODULE(pyopenvino, m) {
regmodule_graph_passes(m);
regmodule_graph_util(m);
regmodule_graph_layout_helpers(m);
regclass_graph_Variant(m);
regclass_graph_Any(m);
regclass_graph_Output<ov::Node>(m, std::string(""));
regclass_graph_Output<const ov::Node>(m, std::string("Const"));

View File

@@ -1,86 +1,86 @@
from openvino.runtime import Variant
from openvino.runtime import OVAny
def test_variant_str():
var = Variant("test_string")
def test_any_str():
var = OVAny("test_string")
assert isinstance(var.value, str)
assert var == "test_string"
def test_variant_int():
var = Variant(2137)
def test_any_int():
var = OVAny(2137)
assert isinstance(var.value, int)
assert var == 2137
def test_variant_float():
var = Variant(21.37)
def test_any_float():
var = OVAny(21.37)
assert isinstance(var.value, float)
def test_variant_string_list():
var = Variant(["test", "string"])
def test_any_string_list():
var = OVAny(["test", "string"])
assert isinstance(var.value, list)
assert isinstance(var[0], str)
assert var[0] == "test"
def test_variant_int_list():
v = Variant([21, 37])
def test_any_int_list():
v = OVAny([21, 37])
assert isinstance(v.value, list)
assert len(v) == 2
assert isinstance(v[0], int)
def test_variant_float_list():
v = Variant([21.0, 37.0])
def test_any_float_list():
v = OVAny([21.0, 37.0])
assert isinstance(v.value, list)
assert len(v) == 2
assert isinstance(v[0], float)
def test_variant_tuple():
v = Variant((2, 1))
def test_any_tuple():
v = OVAny((2, 1))
assert isinstance(v.value, tuple)
def test_variant_bool():
v = Variant(False)
def test_any_bool():
v = OVAny(False)
assert isinstance(v.value, bool)
assert v is not True
def test_variant_dict_str():
v = Variant({"key": "value"})
def test_any_dict_str():
v = OVAny({"key": "value"})
assert isinstance(v.value, dict)
assert v["key"] == "value"
def test_variant_dict_str_int():
v = Variant({"key": 2})
def test_any_dict_str_int():
v = OVAny({"key": 2})
assert isinstance(v.value, dict)
assert v["key"] == 2
def test_variant_int_dict():
v = Variant({1: 2})
def test_any_int_dict():
v = OVAny({1: 2})
assert isinstance(v.value, dict)
assert v[1] == 2
def test_variant_set_new_value():
v = Variant(int(1))
def test_any_set_new_value():
v = OVAny(int(1))
assert isinstance(v.value, int)
v = Variant("test")
v = OVAny("test")
assert isinstance(v.value, str)
assert v == "test"
def test_variant_class():
def test_any_class():
class TestClass:
def __init__(self):
self.text = "test"
v = Variant(TestClass())
v = OVAny(TestClass())
assert isinstance(v.value, TestClass)
assert v.value.text == "test"

View File

@@ -9,7 +9,7 @@ import pytest
import openvino.runtime.opset8 as ops
import openvino.runtime as ov
from openvino.pyopenvino import Variant
from openvino.pyopenvino import OVAny
from openvino.runtime.exceptions import UserInputError
from openvino.runtime import Model, PartialShape, Shape, Type, layout_helpers
@@ -489,18 +489,18 @@ def test_node_target_inputs_soruce_output():
assert np.equal([in_model1.get_shape()], [model.get_output_shape(0)]).all()
def test_variants():
variant_int = Variant(32)
variant_str = Variant("test_text")
def test_any():
any_int = OVAny(32)
any_str = OVAny("test_text")
assert variant_int.get() == 32
assert variant_str.get() == "test_text"
assert any_int.get() == 32
assert any_str.get() == "test_text"
variant_int.set(777)
variant_str.set("another_text")
any_int.set(777)
any_str.set("another_text")
assert variant_int.get() == 777
assert variant_str.get() == "another_text"
assert any_int.get() == 777
assert any_str.get() == "another_text"
def test_runtime_info():