[MO][TF FE] Handle constant with undefined value (#17311) (#24382)

**Details:** Since TF 2.10 the native model freezing can produce
constants with undefined value, i.e. tensor shape can be any and value
is []. In this case the tensor just fills up with the default value (0 -
for numerics, "" - for strings)

**Ticket:** 140458

Porting of https://github.com/openvinotoolkit/openvino/pull/17311

Signed-off-by: Kazantsev, Roman <roman.kazantsev@intel.com>
This commit is contained in:
Roman Kazantsev 2024-05-08 12:15:17 +04:00 committed by GitHub
parent e2c7e4d7b4
commit c9ea173202
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 153 additions and 2 deletions

View File

@ -82,7 +82,7 @@ def tf_tensor_content(tf_dtype, shape, pb_tensor):
value_length = len(value)
except TypeError:
# case, when value is a scalar
value_length = 0
return value
if value_length == 1:
# return scalar if shape is [] otherwise broadcast according to shape
try:
@ -91,18 +91,33 @@ def tf_tensor_content(tf_dtype, shape, pb_tensor):
log.error(decode_err_msg, extra={'is_warning': True})
return mo_array(value[0])
else:
if len(shape) == 0 and value_length == 0:
# Since TF 2.10 the model freezing can produce constants with non-empty tensor
# but with undefined value []
# in this case, the tensor is filled with the default value
# that is 0 for numeric types and "" for string
default_value = 0 if type_helper[0] != str else ""
value = mo_array(default_value, dtype=type_helper[0])
# no shape, return value as is
return value
if len(value) != shape.prod():
log.warning("Shape and content size of tensor don't match, shape: {} content size: {}".
format(shape, len(value)))
if len(value) == 0:
# Since TF 2.10 the model freezing can produce constants with non-empty tensor but with undefined value []
# In this case, the tensor is filled with the default value that is 0 for numeric types and "" for string
default_value = 0 if type_helper[0] != str else ""
value_flatten = mo_array([default_value], dtype=type_helper[0])
else:
value_flatten = value.flatten()
# broadcast semantics according to TensorFlow v1.5 documentation:
# The argument value can be a constant value, or a list of values of type dtype. If value is a list,
# then the length of the list must be less than or equal to the number of elements implied by the shape
# argument (if specified). In the case where the list length is less than the number of elements specified
# by shape, the last element in the list will be used to fill the remaining entries.
value_flatten = value.flatten()
add_value = value_flatten[-1]
add_length = shape.prod() - len(value_flatten)
value = np.concatenate([value_flatten, np.full([add_length], add_value)])

View File

@ -0,0 +1,58 @@
node {
name: "x"
op: "Placeholder"
attr {
key: "dtype"
value {
type: DT_FLOAT
}
}
attr {
key: "shape"
value {
shape {
dim {
size: 2
}
dim {
size: 3
}
}
}
}
}
node {
name: "Const"
op: "Const"
attr {
key: "dtype"
value {
type: DT_FLOAT
}
}
attr {
key: "value"
value {
tensor {
dtype: DT_FLOAT
tensor_shape {
dim {
size: 3
}
}
}
}
}
}
node {
name: "add"
op: "AddV2"
input: "x"
input: "Const"
attr {
key: "T"
value {
type: DT_FLOAT
}
}
}

View File

@ -0,0 +1,13 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import tensorflow.compat.v1 as tf
tf.reset_default_graph()
# Create the graph and model
with tf.Session() as sess:
x = tf.placeholder(tf.float32, [2, 3], 'x')
const = tf.constant(value=[], dtype=tf.float32, shape=[3], name='Const')
tf.add(x, const, name="add")
tf.global_variables_initializer()
tf.io.write_graph(sess.graph, './', 'model_add_with_undefined_constant.pbtxt', as_text=True)

View File

@ -0,0 +1,52 @@
node {
name: "x"
op: "Placeholder"
attr {
key: "dtype"
value {
type: DT_INT32
}
}
attr {
key: "shape"
value {
shape {
dim {
size: 2
}
}
}
}
}
node {
name: "Const"
op: "Const"
attr {
key: "dtype"
value {
type: DT_INT32
}
}
attr {
key: "value"
value {
tensor {
dtype: DT_INT32
tensor_shape {
}
}
}
}
}
node {
name: "mul"
op: "Mul"
input: "x"
input: "Const"
attr {
key: "T"
value {
type: DT_INT32
}
}
}

View File

@ -0,0 +1,13 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import tensorflow.compat.v1 as tf
tf.reset_default_graph()
# Create the graph and model
with tf.Session() as sess:
x = tf.placeholder(tf.int32, [2], 'x')
const = tf.constant(value=[], dtype=tf.int32, shape=[], name='Const')
tf.multiply(x, const, name="mul")
tf.global_variables_initializer()
tf.io.write_graph(sess.graph, './', 'model_mul_with_undefined_constant.pbtxt', as_text=True)