Skip to content

Commit b1a07c7

Browse files
authored
[PyOV] small improvements (#29404)
### Details: - `has_evaluate` is now also optional method for python implementation - improve error message in tensor ctor ### Tickets: - *ticket-id*
1 parent ac3469b commit b1a07c7

File tree

3 files changed

+35
-12
lines changed

3 files changed

+35
-12
lines changed

src/bindings/python/src/pyopenvino/core/tensor.cpp

+12-11
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,8 @@ void regclass_Tensor(py::module m) {
216216

217217
cls.def(py::init([](py::object& image) {
218218
if (!py::isinstance(image, py::module::import("PIL.Image").attr("Image"))) {
219-
throw py::type_error("Input must be a PIL.Image.Image object");
219+
throw py::type_error(
220+
"Input argument must be a PIL.Image.Image/numpy.array/List[int, float, str] object");
220221
}
221222
auto numpy = py::module::import("numpy");
222223
py::array np_array = numpy.attr("array")(image);
@@ -225,19 +226,19 @@ void regclass_Tensor(py::module m) {
225226
}),
226227
py::arg("image"),
227228
R"(
228-
Constructs Tensor from a Pillow Image.
229+
Constructs Tensor from a Pillow Image.
229230
230-
:param image: Pillow Image to create the tensor from.
231-
:type image: PIL.Image.Image
232-
:Example:
233-
.. code-block:: python
231+
:param image: Pillow Image to create the tensor from.
232+
:type image: PIL.Image.Image
233+
:Example:
234+
.. code-block:: python
234235
235-
from PIL import Image
236-
import openvino as ov
236+
from PIL import Image
237+
import openvino as ov
237238
238-
img = Image.open("example.jpg")
239-
tensor = ov.Tensor(img)
240-
)");
239+
img = Image.open("example.jpg")
240+
tensor = ov.Tensor(img)
241+
)");
241242

242243
cls.def("get_element_type",
243244
&ov::Tensor::get_element_type,

src/bindings/python/src/pyopenvino/graph/op.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,17 @@ bool PyOp::evaluate(ov::TensorVector& output_values, const ov::TensorVector& inp
5353
}
5454

5555
bool PyOp::has_evaluate() const {
56-
PYBIND11_OVERRIDE(bool, ov::op::Op, has_evaluate);
56+
py::gil_scoped_acquire gil; // Acquire the GIL while in this scope.
57+
// Try to look up the overridden method on the Python side.
58+
py::function overrided_py_method = pybind11::get_override(this, "has_evaluate");
59+
if (overrided_py_method) { // method is found
60+
return static_cast<py::bool_>(overrided_py_method()); // Call the Python function.
61+
}
62+
py::function overrided_evaluate_method = pybind11::get_override(this, "evaluate");
63+
if (overrided_evaluate_method) {
64+
return true;
65+
}
66+
return false;
5767
}
5868

5969
void PyOp::update_type_info() {

src/bindings/python/tests/test_graph/test_custom_op.py

+12
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ def visit_attributes(self, visitor):
106106
visitor.on_attributes(self._attrs)
107107
return True
108108

109+
def evaluate(self, outputs, inputs):
110+
inputs[0].copy_to(outputs[0])
111+
return True
112+
109113

110114
# request - https://docs.pytest.org/en/7.1.x/reference/reference.html#request
111115
@pytest.fixture
@@ -156,6 +160,14 @@ def test_visit_attributes_custom_op(prepared_paths, attributes, expectation, rai
156160
if e is not None:
157161
assert raise_msg in str(e.value)
158162

163+
input_data = np.ones([2, 1], dtype=np.float32)
164+
expected_output = np.maximum(0.0, input_data)
165+
166+
compiled_model = compile_model(model_with_op_attr)
167+
input_tensor = Tensor(input_data)
168+
results = compiled_model({"data1": input_tensor})
169+
assert np.allclose(results[list(results)[0]], expected_output, 1e-4, 1e-4)
170+
159171

160172
def test_custom_add_op():
161173
data1 = np.array([1, 2, 3])

0 commit comments

Comments
 (0)