Tensorflow2 LSTM failed

The following test model contains keras.layers.LSTM layer.

tensorflow2.from_tensorflow failed to convert this model

import tensorflow as tf
from tvm.relay.frontend import tensorflow2
from tensorflow.python.framework.convert_to_constants import convert_variables_to_constants_v2

shape = (1, 512)
input_data = tf.random.uniform((1,)+shape, dtype=tf.float32)

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.InputLayer(input_shape=shape, dtype="float32", name="input_1"))
model.add(tf.keras.layers.LSTM(512, input_shape=shape))

res = model(input_data)
print(res.shape)

import shutil, os
if os.path.exists("mymodel"):
  shutil.rmtree("mymodel")

tf.saved_model.save(model, "mymodel")
loaded = tf.saved_model.load("mymodel")
f = loaded.signatures['serving_default']
frozen_func = convert_variables_to_constants_v2(f, lower_control_flow=False)
tf_graph = frozen_func.graph.as_graph_def(add_shapes=True)

shape_dict={'input_1': (1,)+shape}
mod, params = tensorflow2.from_tensorflow(tf_graph, shape=shape_dict)

Stack trace with debug output. Debug output shows parameters of _make.strided_slice(data, begin, end, strides, slice_mode, axes):

====begin, end, strides, slice_mode, axes: [0] [1] [1] end None
====begin, end, strides, slice_mode, axes: [0] [1] [1] end None
====begin, end, strides, slice_mode, axes: [(? + -1), 0, 0] [((? + -1) + 1), ?, 512] [1, 1, 1] end None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.8/dist-packages/tvm-0.8.dev1826+g4b4b3d0e2-py3.8-linux-x86_64.egg/tvm/relay/frontend/tensorflow2.py", line 851, in from_tensorflow
    func, params = g.from_tensorflow(graph_def, layout, shape, outputs, gdef_lib=graph_def_library)
  File "/usr/local/lib/python3.8/dist-packages/tvm-0.8.dev1826+g4b4b3d0e2-py3.8-linux-x86_64.egg/tvm/relay/frontend/tensorflow2.py", line 230, in from_tensorflow
    func = self._get_relay_func(
  File "/usr/local/lib/python3.8/dist-packages/tvm-0.8.dev1826+g4b4b3d0e2-py3.8-linux-x86_64.egg/tvm/relay/frontend/tensorflow2.py", line 392, in _get_relay_func
    self._backtrack_construct(graph, node.name)
  File "/usr/local/lib/python3.8/dist-packages/tvm-0.8.dev1826+g4b4b3d0e2-py3.8-linux-x86_64.egg/tvm/relay/frontend/tensorflow2.py", line 586, in _backtrack_construct
    op = self._convert_operator(graph, node.op, node.name, inputs, attr)
  File "/usr/local/lib/python3.8/dist-packages/tvm-0.8.dev1826+g4b4b3d0e2-py3.8-linux-x86_64.egg/tvm/relay/frontend/tensorflow2.py", line 482, in _convert_operator
    sym = _convert_map_common[op_name](inputs, attrs, self._params, self._module.mod)
  File "/usr/local/lib/python3.8/dist-packages/tvm-0.8.dev1826+g4b4b3d0e2-py3.8-linux-x86_64.egg/tvm/relay/frontend/tensorflow_ops.py", line 2286, in _impl
    out = _op.strided_slice(inputs[0], begin=begin, end=end, strides=stride)
  File "/usr/local/lib/python3.8/dist-packages/tvm-0.8.dev1826+g4b4b3d0e2-py3.8-linux-x86_64.egg/tvm/relay/op/transform.py", line 942, in strided_slice
    return _make.strided_slice(data, begin, end, strides, slice_mode, axes)
  File "/usr/local/lib/python3.8/dist-packages/tvm-0.8.dev1826+g4b4b3d0e2-py3.8-linux-x86_64.egg/tvm/_ffi/_ctypes/packed_func.py", line 237, in __call__
    raise get_last_ffi_error()
tvm._ffi.base.TVMError: Traceback (most recent call last):
  2: TVMFuncCall
  1: tvm::runtime::TypedPackedFunc<tvm::RelayExpr (tvm::RelayExpr, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::String, tvm::runtime::Optional<tvm::runtime::Array<tvm::Integer, void> >)>::AssignTypedLambda<tvm::RelayExpr (*)(tvm::RelayExpr, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::String, tvm::runtime::Optional<tvm::runtime::Array<tvm::Integer, void> >)>(tvm::RelayExpr (*)(tvm::RelayExpr, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::String, tvm::runtime::Optional<tvm::runtime::Array<tvm::Integer, void> >), std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)::{lambda(tvm::runtime::TVMArgs const&, tvm::runtime::TVMRetValue*)#1}::operator()(tvm::runtime::TVMArgs const&, tvm::runtime::TVMRetValue*) const
  0: tvm::runtime::TVMMovableArgValueWithContext_::operator tvm::runtime::Array<tvm::Integer, void><tvm::runtime::Array<tvm::Integer, void> >() const
  3: TVMFuncCall
  2: tvm::runtime::TypedPackedFunc<tvm::RelayExpr (tvm::RelayExpr, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::String, tvm::runtime::Optional<tvm::runtime::Array<tvm::Integer, void> >)>::AssignTypedLambda<tvm::RelayExpr (*)(tvm::RelayExpr, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::String, tvm::runtime::Optional<tvm::runtime::Array<tvm::Integer, void> >)>(tvm::RelayExpr (*)(tvm::RelayExpr, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::Array<tvm::Integer, void>, tvm::runtime::String, tvm::runtime::Optional<tvm::runtime::Array<tvm::Integer, void> >), std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)::{lambda(tvm::runtime::TVMArgs const&, tvm::runtime::TVMRetValue*)#1}::operator()(tvm::runtime::TVMArgs const&, tvm::runtime::TVMRetValue*) const
  1: tvm::runtime::TVMMovableArgValueWithContext_::operator tvm::runtime::Array<tvm::Integer, void><tvm::runtime::Array<tvm::Integer, void> >() const
  0: tvm::runtime::Array<tvm::Integer, void> tvm::runtime::TVMPODValue_::AsObjectRef<tvm::runtime::Array<tvm::Integer, void> >() const
  File "/root/workspace/tvm/include/tvm/runtime/packed_func.h", line 714
TVMError: In function relay.op._make.strided_slice: error while converting argument 2: [00:39:57] /root/workspace/tvm/include/tvm/runtime/packed_func.h:1591: 
---------------------------------------------------------------
An error occurred during the execution of TVM.
For more information, please see: https://tvm.apache.org/docs/errors.html
---------------------------------------------------------------
  Check failed: (!checked_type.defined()) is false: Expected Array[IntImm], but got Array[index 0: tir.Add]

Looks like the problem is in begin and end values. Instead of integer numbers they contain expression (? + -1) - Any plus -1. which was calculated in _transform_mask. The values are

# _transform_mask - inside if mask & shrink_axis_mask block
data_shape: (?, ?, 512)
begin: [-1]

m_begin[0] = data_shape[0] + begin[0]
# as a result m_begin is [(? + -1), 0, 0]

@lixiaoquan @yongwww

To convert the model to Relay I had to “fix” begin, end and final_output values inside the code

begin: [(? + -1), 0, 0] -> [0 ,0, 0]
end: [((? + -1) + 1), ?, 512] -> [1, 1, 512]
final_output: [?, 512] -> [1, 512]

here and here