[Tests][TFLite] Add SQUEEZE, REVERSE_SEQUENCE, UNPACK, and ZEROS_LIKE coverage#19814
[Tests][TFLite] Add SQUEEZE, REVERSE_SEQUENCE, UNPACK, and ZEROS_LIKE coverage#19814Aharrypotter wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates the TFLite frontend in TVM Relax by implementing the conversion of REVERSE_SEQUENCE using topi.reverse_sequence via call_dps_packed and refactoring the UNPACK conversion. It also adds unit tests for several operators. The review feedback correctly identifies that topi.reverse_sequence expects four arguments, and omitting batch_axis could lead to runtime errors. It suggests explicitly passing batch_axis in both the frontend implementation and the corresponding test cases.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| return relax.op.call_dps_packed( | ||
| "topi.reverse_sequence", | ||
| (in_expr, length_expr, seq_axis), | ||
| out_sinfo=relax.TensorStructInfo(output_shape, output_dtype), | ||
| ) |
There was a problem hiding this comment.
The topi.reverse_sequence operator expects 4 arguments: (data, seq_lengths, seq_axis, batch_axis). Omitting batch_axis can lead to runtime errors (such as arity mismatch) when calling the packed function, especially in non-Python runtimes or environments where default arguments are not automatically resolved. Since batch_axis is validated to be 0, we should explicitly pass it as the fourth argument.
| return relax.op.call_dps_packed( | |
| "topi.reverse_sequence", | |
| (in_expr, length_expr, seq_axis), | |
| out_sinfo=relax.TensorStructInfo(output_shape, output_dtype), | |
| ) | |
| return relax.op.call_dps_packed( | |
| "topi.reverse_sequence", | |
| (in_expr, length_expr, seq_axis, batch_axis), | |
| out_sinfo=relax.TensorStructInfo(output_shape, output_dtype), | |
| ) |
There was a problem hiding this comment.
Thanks for the careful check. I looked at the current packed registration in
src/topi/transform.cc, and topi.reverse_sequence is registered as a
3-argument packed function:
.def_packed("topi.reverse_sequence",
[](ffi::PackedArgs args, ffi::Any* rv) {
*rv = reverse_sequence(args[0].cast<te::Tensor>(),
args[1].cast<te::Tensor>(),
args[2].cast<int>());
})So passing (data, seq_lengths, seq_axis, batch_axis) from Relax would not match
the current packed API. The frontend already rejects batch_dim != 0 before the
call, and the 3-argument packed wrapper therefore intentionally uses TOPI's
default batch_axis=0.
I think the current 3-argument call and the matching Expected IR are the safer
form for this PR. If we want to support non-zero batch_dim later, the right
follow-up would be to first extend the topi.reverse_sequence packed
registration to consume args[3], and then update the TFLite frontend and test
expectation to pass batch_axis explicitly.
| gv: R.Tensor((2, 4, 3), dtype="float32") = R.call_dps_packed( | ||
| "topi.reverse_sequence", | ||
| (tvmgen_tensor_0, tvmgen_tensor_1, 1), | ||
| out_sinfo=R.Tensor((2, 4, 3), dtype="float32"), | ||
| ) |
There was a problem hiding this comment.
Update the expected IR module to match the explicit passing of batch_axis (which is 0) to topi.reverse_sequence.
| gv: R.Tensor((2, 4, 3), dtype="float32") = R.call_dps_packed( | |
| "topi.reverse_sequence", | |
| (tvmgen_tensor_0, tvmgen_tensor_1, 1), | |
| out_sinfo=R.Tensor((2, 4, 3), dtype="float32"), | |
| ) | |
| gv: R.Tensor((2, 4, 3), dtype="float32") = R.call_dps_packed( | |
| "topi.reverse_sequence", | |
| (tvmgen_tensor_0, tvmgen_tensor_1, 1, 0), | |
| out_sinfo=R.Tensor((2, 4, 3), dtype="float32"), | |
| ) |
There was a problem hiding this comment.
Same as above. The current topi.reverse_sequence packed registration only consumes three arguments, and this PR already rejects non-zero batch_dim, so the Expected IR intentionally matches the current 3-argument packed API.
tlopex
left a comment
There was a problem hiding this comment.
I think REVERSE_SEQUENCE needs one more change before merge.
The new lowering emits R.call_dps_packed("topi.reverse_sequence", ...) at python/tvm/relax/frontend/tflite/tflite_frontend.py:5023. However, the registered topi.reverse_sequence packed function in src/topi/transform.cc is a TOPI/TE compute wrapper that casts the first two arguments to te::Tensor. call_dps_packed invokes the symbol at runtime with runtime tensors, so the imported model fails when compiled and executed.
I reproduced this with the new hand-built REVERSE_SEQUENCE model: the structural test passes, but running the compiled module fails with:
TypeError: Cannot convert from type `ffi.Tensor` to `te.Tensor`
Could we either lower this through a real TIR path, e.g. BlockBuilder.emit_te(topi.reverse_sequence, ...), or provide a proper runtime DPS packed implementation? It would also be good to add a runtime regression test for REVERSE_SEQUENCE, since the current test only checks the generated IR shape.
Summary
Adds Relax TFLite frontend coverage for the remaining unchecked
non-quantized operator tests tracked in #18971:
SQUEEZEREVERSE_SEQUENCEUNPACKZEROS_LIKEThe tests use small hand-built TFLite flatbuffers and compare the generated
Relax IR with explicit Expected IRModules. This avoids TensorFlow Lite
converter optimizations that rewrite
SQUEEZEtoRESHAPEor foldZEROS_LIKE, and keeps the operator-focused tests tied directly to the targetTFLite builtin operators.
Changes
SQUEEZEwithSqueezeOptionsREVERSE_SEQUENCEwithReverseSequenceOptionsUNPACKwithUnpackOptionsZEROS_LIKEwithZerosLikeOptionstests/python/relax/test_frontend_tflite.py.REVERSE_SEQUENCElowering to use the existingtopi.reverse_sequenceDPS packed path instead of the nonexistentrelax.op.reverse_sequencePython op.REVERSE_SEQUENCEwith non-zerobatch_dimas unsupported, matchingthe currently available TOPI packed wrapper.
UNPACKlowering to build tuple outputs using explicitTupleGetItem(split_result, i)access, avoiding Python iteration over aRelax expression.
Tests
Local validation:
python -m ruff format \ python/tvm/relax/frontend/tflite/tflite_frontend.py \ tests/python/relax/test_frontend_tflite.py python -m ruff check \ python/tvm/relax/frontend/tflite/tflite_frontend.py \ tests/python/relax/test_frontend_tflite.py python -m pytest \ tests/python/relax/test_frontend_tflite.py \ -k "squeeze or reverse_sequence or unpack or zeros_like" \ -q python -m pytest tests/python/relax/test_frontend_tflite.py -qResult:
References