Sets the shape of `tensor` to the `shape`'s constant value, if inferrable. This is a temporary workaround to fix shape inference across functional op boundaries. E.g. ```python shape = tf.constant([3]) @tf.function def f(): u = tf.random_uniform(shape) return u ``` If we w
(tensor, shape)
| 969 | |
| 970 | |
| 971 | def maybe_set_static_shape(tensor, shape): # pylint: disable=invalid-name |
| 972 | """Sets the shape of `tensor` to the `shape`'s constant value, if inferrable. |
| 973 | |
| 974 | This is a temporary workaround to fix shape inference across functional op |
| 975 | boundaries. E.g. |
| 976 | |
| 977 | ```python |
| 978 | shape = tf.constant([3]) |
| 979 | @tf.function |
| 980 | def f(): |
| 981 | u = tf.random_uniform(shape) |
| 982 | return u |
| 983 | ``` |
| 984 | |
| 985 | If we were to rely solely on C++ shape inference, the shape of `u` inside |
| 986 | `f` would be unknown because C++ shape inference is not aware of the outer |
| 987 | graph and all it sees is a Placeholder node when backtracing the captured |
| 988 | tensor for `shape`. `maybe_set_static_shape` computes the static shape value |
| 989 | of `shape` by traversing the `FuncGraph` boundaries and sets the correct |
| 990 | shape. |
| 991 | |
| 992 | A longer term solution would be to fix C++ shape inference. |
| 993 | |
| 994 | Args: |
| 995 | tensor: A tensor. |
| 996 | shape: A shape tensor. |
| 997 | """ |
| 998 | if (_ENABLE_MAYBE_SET_STATIC_SHAPE and not context.executing_eagerly() and |
| 999 | ops.get_default_graph().building_function and |
| 1000 | not tensor.shape.is_fully_defined() and is_tensor(shape)): |
| 1001 | shape = shape_tensor(shape) |
| 1002 | const_shape = constant_value_as_shape(shape) |
| 1003 | tensor.set_shape(const_shape) |
nothing calls this directly
no test coverage detected