From a97a8146d9be8ab4c0661c3d57d95ec5fb35b49c Mon Sep 17 00:00:00 2001 From: Maxim Vafin Date: Wed, 22 Feb 2023 21:25:56 +0100 Subject: [PATCH 1/5] Use shared constant in pytorch decoder --- .../src/openvino/frontend/pytorch/decoder.py | 49 ++++--------------- .../src/pyopenvino/graph/ops/constant.cpp | 6 --- 2 files changed, 9 insertions(+), 46 deletions(-) diff --git a/src/bindings/python/src/openvino/frontend/pytorch/decoder.py b/src/bindings/python/src/openvino/frontend/pytorch/decoder.py index 2ceee453636dd0..ee29fa57bb8229 100644 --- a/src/bindings/python/src/openvino/frontend/pytorch/decoder.py +++ b/src/bindings/python/src/openvino/frontend/pytorch/decoder.py @@ -36,18 +36,9 @@ def ivalue_to_constant(ivalue): assert ov_type.is_static(), "Can't deduce type for list" return op.Constant(ov_type, Shape([len(ivalue)]), ivalue).outputs() - if isinstance(ivalue, torch.Tensor) and ivalue.type() in pt_to_ov_type_map: - try: - ovshape = PartialShape(ivalue.size()) - ovtype = pt_to_ov_type_map[ivalue.type()] - ov_const = op.Constant(ovtype, ovshape.get_shape(), ivalue.data_ptr()) - except Exception: - # old variant that makes a slow data copying - warnings.warn("[ WARNING ] Constant wasn't able to convert from data_ptr.") - nvalues = ivalue.numpy() - ovtype = np_to_ov_type_map[str(nvalues.dtype)] - ovshape = PartialShape(nvalues.shape) - ov_const = op.Constant(ovtype, ovshape.get_shape(), nvalues.flatten().tolist()) + if isinstance(ivalue, torch.Tensor): + ivalue = ivalue.to(memory_format=torch.contiguous_format) + ov_const = op.Constant(ivalue.numpy(force=True), shared_memory=True) return ov_const.outputs() return None @@ -89,11 +80,6 @@ def get_value_from_getattr(getattr_node, self_module): "torch.BoolTensor": OVType.boolean, } -np_to_ov_type_map = { - "float32": OVType.f32, - "int32": OVType.i32, -} - class TorchScriptPythonDecoder (Decoder): def __init__(self, pt_module, graph_element=None): @@ -265,29 +251,12 @@ def as_string(self): def _as_constant_tensor(pt_value: torch.Value): ivalue = pt_value.toIValue() if pt_value.isCompleteTensor(): - try: - ivalue = ivalue.to(memory_format=torch.contiguous_format).detach().cpu() - except Exception: - warnings.warn("[ WARNING ] Tensor couldn't detach") - if str(pt_value.type().dtype()) in pt_to_ov_type_map: - # Constant interpretation doesn't respect new-full type of PT - # It recognizes only tensors, and give lists as 1D tensors, and scalars as Tensor scalars - # So only tensor-type constants are supported - ovshape = PartialShape(pt_value.type().sizes()) - ovtype = pt_to_ov_type_map[str(pt_value.type().dtype())] - - # TODO: try-except here is a temporary WA for issues with data_ptr that we currently cannot predict; provide better solution - try: - # this is only possible with adding a new ctor for Constant Python binding - # TODO Check strides and pass them somehow - values = ivalue.data_ptr() - ov_const = op.Constant(ovtype, ovshape.get_shape(), values) - except Exception: - # old variant that makes a slow data copying - warnings.warn("[ WARNING ] Constant wasn't able to convert from data_ptr.") - values = ivalue.flatten().tolist() - ov_const = op.Constant(ovtype, ovshape.get_shape(), values) - return ov_const.outputs() + ivalue = ivalue.to(memory_format=torch.contiguous_format) + # Constant interpretation doesn't respect new-full type of PT + # It recognizes only tensors, and give lists as 1D tensors, and scalars as Tensor scalars + # So only tensor-type constants are supported + ov_const = op.Constant(ivalue.numpy(force=True), shared_memory=True) + return ov_const.outputs() else: return ivalue_to_constant(ivalue) return None diff --git a/src/bindings/python/src/pyopenvino/graph/ops/constant.cpp b/src/bindings/python/src/pyopenvino/graph/ops/constant.cpp index c98dba0db39390..edb8f3bca816f1 100644 --- a/src/bindings/python/src/pyopenvino/graph/ops/constant.cpp +++ b/src/bindings/python/src/pyopenvino/graph/ops/constant.cpp @@ -124,12 +124,6 @@ void regclass_graph_op_Constant(py::module m) { constant.def(py::init&>()); constant.def(py::init&>()); constant.def(py::init&>()); - constant.def(py::init([](const ov::element::Type& et, const ov::Shape& sh, int64_t p) { - // restore pointer from integer - // TODO: Align on bit width - void* pp = reinterpret_cast(p); - return std::make_shared(et, sh, pp); - })); constant.def("get_value_strings", &ov::op::v0::Constant::get_value_strings); From 23d39953e2be15df714d9e2d63898ff79171663e Mon Sep 17 00:00:00 2001 From: Maxim Vafin Date: Wed, 22 Feb 2023 22:20:13 +0100 Subject: [PATCH 2/5] Fix contigious array --- .../python/src/openvino/frontend/pytorch/decoder.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/bindings/python/src/openvino/frontend/pytorch/decoder.py b/src/bindings/python/src/openvino/frontend/pytorch/decoder.py index ee29fa57bb8229..be1633ae6628dd 100644 --- a/src/bindings/python/src/openvino/frontend/pytorch/decoder.py +++ b/src/bindings/python/src/openvino/frontend/pytorch/decoder.py @@ -10,6 +10,7 @@ import warnings import torch +import numpy as np def get_type_from_py_type(value): @@ -38,7 +39,10 @@ def ivalue_to_constant(ivalue): if isinstance(ivalue, torch.Tensor): ivalue = ivalue.to(memory_format=torch.contiguous_format) - ov_const = op.Constant(ivalue.numpy(force=True), shared_memory=True) + narr = ivalue.numpy(force=True) + if not narr.flags['C_CONTIGUOUS']: + narr = np.ascontiguousarray(narr) + ov_const = op.Constant(narr, shared_memory=True) return ov_const.outputs() return None @@ -252,10 +256,13 @@ def _as_constant_tensor(pt_value: torch.Value): ivalue = pt_value.toIValue() if pt_value.isCompleteTensor(): ivalue = ivalue.to(memory_format=torch.contiguous_format) + narr = ivalue.numpy(force=True) + if not narr.flags['C_CONTIGUOUS']: + narr = np.ascontiguousarray(narr) # Constant interpretation doesn't respect new-full type of PT # It recognizes only tensors, and give lists as 1D tensors, and scalars as Tensor scalars # So only tensor-type constants are supported - ov_const = op.Constant(ivalue.numpy(force=True), shared_memory=True) + ov_const = op.Constant(narr, shared_memory=True) return ov_const.outputs() else: return ivalue_to_constant(ivalue) From 0d10932b5bde66abd5715d092ef21970a3b4b212 Mon Sep 17 00:00:00 2001 From: Maxim Vafin Date: Thu, 23 Feb 2023 14:28:55 +0100 Subject: [PATCH 3/5] Support scalars --- .../src/openvino/frontend/pytorch/decoder.py | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/bindings/python/src/openvino/frontend/pytorch/decoder.py b/src/bindings/python/src/openvino/frontend/pytorch/decoder.py index be1633ae6628dd..4267e611aff19d 100644 --- a/src/bindings/python/src/openvino/frontend/pytorch/decoder.py +++ b/src/bindings/python/src/openvino/frontend/pytorch/decoder.py @@ -38,11 +38,16 @@ def ivalue_to_constant(ivalue): return op.Constant(ov_type, Shape([len(ivalue)]), ivalue).outputs() if isinstance(ivalue, torch.Tensor): - ivalue = ivalue.to(memory_format=torch.contiguous_format) - narr = ivalue.numpy(force=True) - if not narr.flags['C_CONTIGUOUS']: - narr = np.ascontiguousarray(narr) - ov_const = op.Constant(narr, shared_memory=True) + if ivalue.ndim == 0: + assert str(ivalue.dtype()) in pt_to_ov_type_map, "Type is not known" + ov_type = pt_to_ov_type_map[str(ivalue.dtype)] + ov_const = op.Constant(ov_type, Shape([]), [ivalue.item()]) + else: + ivalue = ivalue.to(memory_format=torch.contiguous_format) + narr = ivalue.numpy(force=True) + if not narr.flags['C_CONTIGUOUS']: + narr = np.ascontiguousarray(narr) + ov_const = op.Constant(narr, shared_memory=True) return ov_const.outputs() return None @@ -255,14 +260,19 @@ def as_string(self): def _as_constant_tensor(pt_value: torch.Value): ivalue = pt_value.toIValue() if pt_value.isCompleteTensor(): - ivalue = ivalue.to(memory_format=torch.contiguous_format) - narr = ivalue.numpy(force=True) - if not narr.flags['C_CONTIGUOUS']: - narr = np.ascontiguousarray(narr) - # Constant interpretation doesn't respect new-full type of PT - # It recognizes only tensors, and give lists as 1D tensors, and scalars as Tensor scalars - # So only tensor-type constants are supported - ov_const = op.Constant(narr, shared_memory=True) + if ivalue.ndim == 0: + assert str(ivalue.dtype) in pt_to_ov_type_map, "Type is not known" + ov_type = pt_to_ov_type_map[str(ivalue.dtype)] + ov_const = op.Constant(ov_type, Shape([]), [ivalue.item()]) + else: + ivalue = ivalue.to(memory_format=torch.contiguous_format) + narr = ivalue.numpy(force=True) + if not narr.flags['C_CONTIGUOUS']: + narr = np.ascontiguousarray(narr) + # Constant interpretation doesn't respect new-full type of PT + # It recognizes only tensors, and give lists as 1D tensors, and scalars as Tensor scalars + # So only tensor-type constants are supported + ov_const = op.Constant(narr, shared_memory=True) return ov_const.outputs() else: return ivalue_to_constant(ivalue) From 159c83a79ebf7a34a34fa7d753f30ad6a429940d Mon Sep 17 00:00:00 2001 From: Maxim Vafin Date: Fri, 24 Feb 2023 12:17:33 +0100 Subject: [PATCH 4/5] Apply suggestions from code review --- src/bindings/python/src/openvino/frontend/pytorch/decoder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bindings/python/src/openvino/frontend/pytorch/decoder.py b/src/bindings/python/src/openvino/frontend/pytorch/decoder.py index 4267e611aff19d..84de018bb64453 100644 --- a/src/bindings/python/src/openvino/frontend/pytorch/decoder.py +++ b/src/bindings/python/src/openvino/frontend/pytorch/decoder.py @@ -39,7 +39,7 @@ def ivalue_to_constant(ivalue): if isinstance(ivalue, torch.Tensor): if ivalue.ndim == 0: - assert str(ivalue.dtype()) in pt_to_ov_type_map, "Type is not known" + assert str(ivalue.dtype()) in pt_to_ov_type_map, f"Type is not known{ivalue.dtype()}" ov_type = pt_to_ov_type_map[str(ivalue.dtype)] ov_const = op.Constant(ov_type, Shape([]), [ivalue.item()]) else: @@ -261,7 +261,7 @@ def _as_constant_tensor(pt_value: torch.Value): ivalue = pt_value.toIValue() if pt_value.isCompleteTensor(): if ivalue.ndim == 0: - assert str(ivalue.dtype) in pt_to_ov_type_map, "Type is not known" + assert str(ivalue.dtype) in pt_to_ov_type_map, f"Type is not known{ivalue.dtype}" ov_type = pt_to_ov_type_map[str(ivalue.dtype)] ov_const = op.Constant(ov_type, Shape([]), [ivalue.item()]) else: From 3c93ca36c33248225ef3238563324e2aa51fae24 Mon Sep 17 00:00:00 2001 From: Maxim Vafin Date: Fri, 24 Feb 2023 12:40:38 +0100 Subject: [PATCH 5/5] Apply suggestions from code review Co-authored-by: Ekaterina Aidova --- src/bindings/python/src/openvino/frontend/pytorch/decoder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bindings/python/src/openvino/frontend/pytorch/decoder.py b/src/bindings/python/src/openvino/frontend/pytorch/decoder.py index 84de018bb64453..e65f7ba27dff16 100644 --- a/src/bindings/python/src/openvino/frontend/pytorch/decoder.py +++ b/src/bindings/python/src/openvino/frontend/pytorch/decoder.py @@ -39,7 +39,7 @@ def ivalue_to_constant(ivalue): if isinstance(ivalue, torch.Tensor): if ivalue.ndim == 0: - assert str(ivalue.dtype()) in pt_to_ov_type_map, f"Type is not known{ivalue.dtype()}" + assert str(ivalue.dtype()) in pt_to_ov_type_map, f"Type is not known {ivalue.dtype()}" ov_type = pt_to_ov_type_map[str(ivalue.dtype)] ov_const = op.Constant(ov_type, Shape([]), [ivalue.item()]) else: @@ -261,7 +261,7 @@ def _as_constant_tensor(pt_value: torch.Value): ivalue = pt_value.toIValue() if pt_value.isCompleteTensor(): if ivalue.ndim == 0: - assert str(ivalue.dtype) in pt_to_ov_type_map, f"Type is not known{ivalue.dtype}" + assert str(ivalue.dtype) in pt_to_ov_type_map, f"Type is not known {ivalue.dtype}" ov_type = pt_to_ov_type_map[str(ivalue.dtype)] ov_const = op.Constant(ov_type, Shape([]), [ivalue.item()]) else: