[PT FE] Fix for prim::Constant optional or containing list of tensors (#16754)
* Fix Constant list of tensor * Write TorchScript transformation * Handle Optional Tensor Constants * Improve tests * Add comments * Try fix flake
This commit is contained in:
1 parent
b452dab8f0
commit
8e5b0650a0
2 files changed
+137
-1
No files matched your search
@@ -109,6 +109,10 @@ class TorchScriptPythonDecoder (Decoder):
|
||||
if self._input_signature is not None and self.raw_inputs[0].debugName() == "self":
|
||||
self._input_signature.insert(0, "self")
|
||||
|
||||
if isinstance(self.graph_element, torch.Graph):
|
||||
self._transform_tensor_list_constants_to_listconstruct(self.graph_element)
|
||||
self._transform_optional_constants(self.graph_element)
|
||||
|
||||
def _get_scripted_model(self, pt_module, example_inputs=None, freeze=True):
|
||||
import torch
|
||||
import inspect
|
||||
@@ -277,6 +281,7 @@ class TorchScriptPythonDecoder (Decoder):
|
||||
return decoder
|
||||
|
||||
def get_op_type(self) -> str:
|
||||
assert isinstance(self.graph_element, torch.Node), "Function can be called only when self.graph_element is of type torch.Node"
|
||||
return self.graph_element.kind()
|
||||
|
||||
def get_schema(self) -> str:
|
||||
@@ -309,10 +314,11 @@ class TorchScriptPythonDecoder (Decoder):
|
||||
return []
|
||||
|
||||
def as_constant(self):
|
||||
if not isinstance(self.graph_element, torch.Node):
|
||||
return None
|
||||
if not self.get_op_type() == "prim::Constant":
|
||||
return None
|
||||
pt_value = self._raw_output(0)
|
||||
|
||||
pt_type = pt_value.type()
|
||||
if isinstance(pt_type, torch.TensorType):
|
||||
return ivalue_to_constant(pt_value.toIValue())
|
||||
@@ -369,3 +375,48 @@ class TorchScriptPythonDecoder (Decoder):
|
||||
pt_value = get_value_from_getattr(in_node, self.pt_module)
|
||||
return pt_value is None
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _transform_tensor_list_constants_to_listconstruct(graph: torch.Graph):
|
||||
# Function replaces prim::Constant containing List of Tensors with
|
||||
# prim::ListConstruct containing prim::Constant Tensors.
|
||||
assert isinstance(graph, torch.Graph), "Function can be called only with parameters of type torch.Graph."
|
||||
for node in graph.nodes():
|
||||
if node.kind() != "prim::Constant":
|
||||
continue
|
||||
output_type = node.output().type()
|
||||
allowed_types = [
|
||||
output_type.isSubtypeOf(torch.ListType.ofTensors()),
|
||||
output_type.isSubtypeOf(torch.ListType(torch.OptionalType.ofTensor())),
|
||||
]
|
||||
if not any(allowed_types):
|
||||
continue
|
||||
const_inputs = []
|
||||
for val in node.output().toIValue():
|
||||
const_input = graph.insertConstant(val)
|
||||
const_input.node().moveBefore(node)
|
||||
const_input.node().copyMetadata(node)
|
||||
const_inputs.append(const_input)
|
||||
|
||||
replacement = graph.create("prim::ListConstruct", const_inputs)
|
||||
replacement.insertBefore(node)
|
||||
replacement.output().setType(torch.ListType.ofTensors())
|
||||
replacement.copyMetadata(node)
|
||||
node.output().replaceAllUsesWith(replacement.output())
|
||||
|
||||
@staticmethod
|
||||
def _transform_optional_constants(graph: torch.Graph):
|
||||
# Function replaces prim::Constant containing torch.OptionalType with
|
||||
# prim::Constant containing torch.NoneType or type of IValue.
|
||||
assert isinstance(graph, torch.Graph), "Function can be called only with parameters of type torch.Graph."
|
||||
for node in graph.nodes():
|
||||
if node.kind() != "prim::Constant":
|
||||
continue
|
||||
output_type = node.output().type()
|
||||
if not isinstance(output_type, torch.OptionalType):
|
||||
continue
|
||||
value = node.output().toIValue()
|
||||
const_input = graph.insertConstant(value)
|
||||
const_input.node().moveBefore(node)
|
||||
const_input.node().copyMetadata(node)
|
||||
node.output().replaceAllUsesWith(const_input)
|
||||
Reference in new issue
Block a user