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 ecf42c1234 [Relax][Frontend][ONNX] Fix LpPool conversion (#20053)
ecf42c1234 is described below

commit ecf42c123456270516eb6c745f45c80b2458cde7
Author: Ronald Nap <[email protected]>
AuthorDate: Sun Jul 26 22:08:26 2026 -0700

    [Relax][Frontend][ONNX] Fix LpPool conversion (#20053)
    
    ## Summary
    
    Fixes two issues in the Relax ONNX `LpPool` converter:
    
    - Computes `|x|^p` instead of `x^p`, matching the [official ONNX
    reference
    
implementation](https://github.com/onnx/onnx/blob/main/onnx/reference/ops/op_pool_common.py#L255).
    - Passes the TVM dtype directly to `relax.const`, avoiding a NumPy dtype
    conversion failure.
    
    ## Minimal reproduce
    
    ```python
    python -m pytest \
      tests/python/relax/test_frontend_onnx.py::test_pool \
      -vv
    ```
    
    conversion failed with:
    
    ```text
    ValueError: Could not convert T.float32 to a NumPy dtype
    ```
---
 python/tvm/relax/frontend/onnx/onnx_frontend.py |  6 +--
 tests/python/relax/test_frontend_onnx.py        | 56 ++++++++++++++++++++++---
 2 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/python/tvm/relax/frontend/onnx/onnx_frontend.py 
b/python/tvm/relax/frontend/onnx/onnx_frontend.py
index 806d16f5a8..6d38d2b2ca 100644
--- a/python/tvm/relax/frontend/onnx/onnx_frontend.py
+++ b/python/tvm/relax/frontend/onnx/onnx_frontend.py
@@ -4016,12 +4016,12 @@ class LpPool(OnnxOpConverter):
         dtype = inputs[0].ty.dtype
         p = attr.get("p", 2.0)
         reci_p = relax.const(1.0 / p, dtype=dtype)
-        # emit for get ty
-        data = bb.emit(relax.op.power(inputs[0], relax.const(p, dtype=dtype)))
+
+        data = bb.emit(relax.op.power(relax.op.abs(inputs[0]), relax.const(p, 
dtype=dtype)))
         attr.update({"count_include_pad": True})
         avg_pool = AveragePool._impl_v1(bb, [data], attr, params)
         kernels = attr["kernel_shape"]
-        out = avg_pool * relax.const(_np.prod(kernels).astype(dtype))
+        out = avg_pool * relax.const(_np.prod(kernels), dtype=dtype)
         return relax.op.power(out, reci_p)
 
 
diff --git a/tests/python/relax/test_frontend_onnx.py 
b/tests/python/relax/test_frontend_onnx.py
index 3a0a4aa5b9..730a969b62 100644
--- a/tests/python/relax/test_frontend_onnx.py
+++ b/tests/python/relax/test_frontend_onnx.py
@@ -8326,9 +8326,10 @@ def test_pool():
             def main(x: R.Tensor(input_shape, dtype="float32")):
                 R.func_attr({"num_input": 1})
                 with R.dataflow():
-                    lv = R.power(x, R.const(2.0, "float32"))
-                    lv1 = pool_op(
-                        lv,
+                    lv = R.abs(x)
+                    lv1 = R.power(lv, R.const(2.0, "float32"))
+                    lv2 = pool_op(
+                        lv1,
                         pool_size=pool_size,
                         strides=strides,
                         dilation=dilation,
@@ -8338,8 +8339,8 @@ def test_pool():
                         layout=layout,
                         out_layout=layout,
                     )
-                    lv2 = R.multiply(lv1, R.const(kernel_elements, "float32"))
-                    gv = R.power(lv2, R.const(0.5, "float32"))
+                    lv3 = R.multiply(lv2, R.const(kernel_elements, "float32"))
+                    gv = R.power(lv3, R.const(0.5, "float32"))
                     R.output(gv)
                 return gv
 
@@ -8379,6 +8380,51 @@ def test_pool():
             )
 
 
[email protected]("p", [1, 3])
+def test_lppool_negative_input(p: int):
+    input_data = np.array([[[-1.0, 2.0, -3.0, 4.0]]], dtype="float32")
+
+    node = helper.make_node(
+        "LpPool",
+        ["x"],
+        ["y"],
+        kernel_shape=[2],
+        strides=[1],
+        p=p,
+    )
+
+    graph = helper.make_graph(
+        [node],
+        "lppool_negative_input_test",
+        inputs=[
+            helper.make_tensor_value_info(
+                "x",
+                TensorProto.FLOAT,
+                [1, 1, 4],
+            )
+        ],
+        outputs=[
+            helper.make_tensor_value_info(
+                "y",
+                TensorProto.FLOAT,
+                [1, 1, 3],
+            )
+        ],
+    )
+
+    model = helper.make_model(
+        graph,
+        producer_name="lppool_negative_input_test",
+        opset_imports=[helper.make_opsetid("", 18)],
+    )
+
+    check_correctness(
+        model,
+        inputs={"x": input_data},
+        opset=18,
+    )
+
+
 def test_global_average_pool():
     def verify_global_average_pool_ir(input_shape, expected):
         output_shape = input_shape[:2] + [1] * (len(input_shape) - 2)

Reply via email to