Skip to content

Commit

Permalink
Use shared constant in pytorch decoder (#15917)
Browse files Browse the repository at this point in the history
* Use shared constant in pytorch decoder

* Fix contigious array

* Support scalars

* Apply suggestions from code review

* Apply suggestions from code review

Co-authored-by: Ekaterina Aidova <[email protected]>

---------

Co-authored-by: Ekaterina Aidova <[email protected]>
  • Loading branch information
mvafin and eaidova authored Feb 26, 2023
1 parent 39e63ac commit 4fac7ea
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 43 deletions.
60 changes: 23 additions & 37 deletions src/bindings/python/src/openvino/frontend/pytorch/decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import warnings
import torch
import numpy as np


def get_type_from_py_type(value):
Expand All @@ -36,18 +37,17 @@ 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):
if ivalue.ndim == 0:
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:
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

Expand Down Expand Up @@ -89,11 +89,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):
Expand Down Expand Up @@ -265,29 +260,20 @@ 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:
if ivalue.ndim == 0:
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:
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
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()
ov_const = op.Constant(narr, shared_memory=True)
return ov_const.outputs()
else:
return ivalue_to_constant(ivalue)
return None
Expand Down
6 changes: 0 additions & 6 deletions src/bindings/python/src/pyopenvino/graph/ops/constant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,6 @@ void regclass_graph_op_Constant(py::module m) {
constant.def(py::init<const ov::element::Type&, const ov::Shape&, const std::vector<uint16_t>&>());
constant.def(py::init<const ov::element::Type&, const ov::Shape&, const std::vector<uint32_t>&>());
constant.def(py::init<const ov::element::Type&, const ov::Shape&, const std::vector<uint64_t>&>());
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<void*>(p);
return std::make_shared<ov::op::v0::Constant>(et, sh, pp);
}));

constant.def("get_value_strings", &ov::op::v0::Constant::get_value_strings);

Expand Down

0 comments on commit 4fac7ea

Please sign in to comment.