This is an automated email from the ASF dual-hosted git repository.

tlopex pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/main by this push:
     new a9ce41e5a2 [Relax][Frontend][TFLite] Add explicit operator marker 
handling (#19824)
a9ce41e5a2 is described below

commit a9ce41e5a26c26a72fa2dfcc7788acf24f66ffa3
Author: Hongyi Wu <[email protected]>
AuthorDate: Mon Jun 22 10:44:42 2026 +0800

    [Relax][Frontend][TFLite] Add explicit operator marker handling (#19824)
    
    ## Summary
    
    This PR adds explicit Relax TFLite frontend handling for the TFLite
    builtin
    operator markers from #19519 item H:
    
    - `DELEGATE`
    - `PLACEHOLDER_FOR_GREATER_OP_CODES`
    
    These builtins are TFLite marker / pseudo operators rather than ordinary
    tensor
    operators.  The frontend now recognizes them and raises a targeted
    `OpNotImplemented` diagnostic instead of falling through to a generic
    unsupported-operator path.
    
    ## Design
    
    `DELEGATE` marks delegated TFLite subgraphs, and
    `PLACEHOLDER_FOR_GREATER_OP_CODES` is a schema compatibility
    placeholder. They
    do not have Relax tensor semantics to lower. This PR therefore keeps the
    importer conservative:
    
    - both builtin names are added to the TFLite `convert_map`
    - both route to a shared `convert_operator_marker` guard
    - the guard reports that the marker is not a Relax tensor operator
    
    This makes the unsupported status intentional and discoverable without
    mapping
    the markers to synthetic Relax ops.
    
    ## Tests
    
    The tests manually build minimal TFLite flatbuffers containing each
    marker
    builtin and assert that import raises the targeted `OpNotImplemented`.
    
    Local validation:
    
    ```bash
    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 operator_marker_unsupported -q
    ```
    
    Result:
    
    ```text
    ruff format: 2 files left unchanged
    ruff check: All checks passed
    operator_marker_unsupported tests: 2 passed, 535 deselected
    ```
    
    ## References
    
    - Issue #19519 item H: TFLite operator markers
---
 .../tvm/relax/frontend/tflite/tflite_frontend.py   | 10 +++++++++
 tests/python/relax/test_frontend_tflite.py         | 26 ++++++++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/python/tvm/relax/frontend/tflite/tflite_frontend.py 
b/python/tvm/relax/frontend/tflite/tflite_frontend.py
index a087ce5d36..44e9773973 100644
--- a/python/tvm/relax/frontend/tflite/tflite_frontend.py
+++ b/python/tvm/relax/frontend/tflite/tflite_frontend.py
@@ -221,6 +221,7 @@ class OperatorConverter:
             "DENSIFY": self.convert_densify,
             "DEPTH_TO_SPACE": self.convert_depth_to_space,
             "DEPTHWISE_CONV_2D": functools.partial(self.convert_conv, 
conv_type="depthwise"),
+            "DELEGATE": functools.partial(self.convert_operator_marker, 
op_name="DELEGATE"),
             "DEQUANTIZE": self.convert_dequantize,
             "DETECTION_POSTPROCESS": self.convert_detection_postprocess,
             "DILATE": self.convert_dilate,
@@ -292,6 +293,9 @@ class OperatorConverter:
             "PACK": self.convert_pack,
             "PAD": self.convert_pad,
             "PADV2": self.convert_pad,
+            "PLACEHOLDER_FOR_GREATER_OP_CODES": functools.partial(
+                self.convert_operator_marker, 
op_name="PLACEHOLDER_FOR_GREATER_OP_CODES"
+            ),
             "POW": functools.partial(self._convert_elemwise, 
relax_op=_op.power),
             "PRELU": self.convert_prelu,
             "RANGE": self.convert_range,
@@ -492,6 +496,12 @@ class OperatorConverter:
         if len(raise_msg) > 0:
             raise tvm.error.OpNotImplemented(raise_msg)
 
+    def convert_operator_marker(self, op, op_name):
+        """Reject TFLite marker builtins with an explicit diagnostic."""
+        raise tvm.error.OpNotImplemented(
+            f"TFLite operator marker {op_name} is not a Relax tensor operator"
+        )
+
     def unbind(self, data, axis=1):
         """
         This is a modified version compared to the one in common.py.
diff --git a/tests/python/relax/test_frontend_tflite.py 
b/tests/python/relax/test_frontend_tflite.py
index de53735a76..590cc4ac45 100644
--- a/tests/python/relax/test_frontend_tflite.py
+++ b/tests/python/relax/test_frontend_tflite.py
@@ -4384,6 +4384,32 @@ def _get_builtin_operator(builtin_name):
     return getattr(_tfl_builtin_operator, builtin_name)
 
 
+def _build_tflite_operator_marker_model(builtin_name):
+    """Build a minimal model containing a TFLite marker builtin."""
+    builder = flatbuffers.Builder(1024)
+    builtin_op = _get_builtin_operator(builtin_name)
+    op_code = _build_operator_code(builder, builtin_op)
+    tensors = [
+        _build_tensor(builder, 0, [1], tensor_type=_tfl_tensor_type.FLOAT32),
+        _build_tensor(builder, 0, [1], tensor_type=_tfl_tensor_type.FLOAT32),
+    ]
+    op = _build_operator(builder, 0, [0], [1])
+    subgraph = _build_subgraph(builder, tensors=tensors, operators=[op], 
inputs=[0], outputs=[1])
+    return _finish_tflite_model(
+        builder,
+        subgraph=subgraph,
+        operator_codes=[op_code],
+        buffers=[_build_buffer(builder)],
+    )
+
+
[email protected]("builtin_name", ["DELEGATE", 
"PLACEHOLDER_FOR_GREATER_OP_CODES"])
+def test_operator_marker_unsupported(builtin_name):
+    """TFLite marker builtins report explicit unsupported diagnostics."""
+    with pytest.raises(tvm.error.OpNotImplemented, match=f"TFLite operator 
marker {builtin_name}"):
+        
_load_model_from_buffer(_build_tflite_operator_marker_model(builtin_name))
+
+
 def _run_module(mod, *inputs):
     tgt = tvm.target.Target("c")
     ex = tvm.compile(mod, tgt)

Reply via email to