Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use shared constant in pytorch decoder #15917

Merged
merged 6 commits into from
Feb 26, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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()}"
mvafin marked this conversation as resolved.
Show resolved Hide resolved
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)
jiwaszki marked this conversation as resolved.
Show resolved Hide resolved
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}"
mvafin marked this conversation as resolved.
Show resolved Hide resolved
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