**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:
parent
e2c7e4d7b4
commit
c9ea173202
|
|
@ -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)])
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
Loading…
Reference in New Issue