You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tvm.apache.org by ju...@apache.org on 2023/01/21 00:41:18 UTC

[tvm] branch main updated: [Frontend][PaddlePaddle] Add topk op and Fix bug, when the output is a dimension, it … (#13701)

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

junrushao 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 d907de3b35 [Frontend][PaddlePaddle] Add topk op and Fix bug, when the output is a dimension, it … (#13701)
d907de3b35 is described below

commit d907de3b358e3b0052e0c39b71e65f4a509e6459
Author: Wubin <wu...@126.com>
AuthorDate: Sat Jan 21 08:41:07 2023 +0800

    [Frontend][PaddlePaddle] Add topk op and Fix bug, when the output is a dimension, it … (#13701)
    
    There are some operation in PaddlePaddle that output a tensor which shape is [1], meanwhile, the slice op have decrease_axis attr, but it should not be squeezed.
---
 docker/install/ubuntu_install_paddle.sh            |  2 +-
 docker/python/ci-constraints.txt                   |  2 +-
 python/tvm/relay/frontend/paddlepaddle.py          | 35 +++++++++++++++++-
 tests/python/frontend/paddlepaddle/test_forward.py | 42 ++++++++++++++++++++++
 4 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/docker/install/ubuntu_install_paddle.sh b/docker/install/ubuntu_install_paddle.sh
index c7f9d43a3b..386d0fa6e7 100755
--- a/docker/install/ubuntu_install_paddle.sh
+++ b/docker/install/ubuntu_install_paddle.sh
@@ -20,4 +20,4 @@ set -e
 set -u
 set -o pipefail
 
-pip install paddlepaddle==2.1.3
+pip install paddlepaddle==2.4.1
diff --git a/docker/python/ci-constraints.txt b/docker/python/ci-constraints.txt
index 6e586b14ae..003c131704 100644
--- a/docker/python/ci-constraints.txt
+++ b/docker/python/ci-constraints.txt
@@ -23,7 +23,7 @@ oneflow = "==0.7.0"
 onnx = "==1.10.2"
 onnxruntime = "==1.9.0"
 numpy = "==1.19.3"
-paddlepaddle = "==2.1.3"
+paddlepaddle = "==2.4.1"
 pillow = "==9.1.0"
 pylint = "==2.4.4"
 scipy = "==1.7.3"
diff --git a/python/tvm/relay/frontend/paddlepaddle.py b/python/tvm/relay/frontend/paddlepaddle.py
index ffbcf12de5..4927a36252 100644
--- a/python/tvm/relay/frontend/paddlepaddle.py
+++ b/python/tvm/relay/frontend/paddlepaddle.py
@@ -1884,7 +1884,8 @@ def convert_slice(g, op, block):
         strides = _op.const([1] * dims, dtype="int64")
 
     out = _op.strided_slice(data, begin=starts, end=ends, strides=strides)
-    if decrease_axis:
+    out_shape = infer_shape(out)
+    if decrease_axis and len(out_shape) > 1:
         out = _op.squeeze(out, axis=decrease_axis)
     g.add_node(op.output("Out")[0], out)
 
@@ -1998,6 +1999,37 @@ def convert_swish(g, op, block):
     g.add_node(op.output("Out")[0], out)
 
 
+def convert_topk(g, op, block):
+    """Operator converter for topk."""
+
+    data = g.get_node(op.input("X")[0])
+    if op.input("K"):
+        k = g.get_node(op.input("K")[0])
+    else:
+        k = op.attr("k")
+
+    largest = op.attr("largest")
+    is_ascend = not largest
+    axis = op.attr("axis")
+
+    value_names = op.output("Out")
+    indice_names = op.output("Indices")
+
+    out = None
+    indice = None
+    if value_names and indice_names:
+        out, indice = _op.topk(data=data, k=k, axis=axis, ret_type="both", is_ascend=is_ascend)
+    elif value_names:
+        out = _op.topk(data=data, k=k, axis=axis, ret_type="values", is_ascend=is_ascend)
+    elif indice_names:
+        indice = _op.topk(data=data, k=k, axis=axis, ret_type="indices", is_ascend=is_ascend)
+
+    if out is not None:
+        g.add_node(value_names[0], out)
+    if indice is not None:
+        g.add_node(indice_names[0], indice)
+
+
 def convert_transpose(g, op, block):
     """Operator converter for transpose."""
 
@@ -2148,6 +2180,7 @@ _convert_map = {
     "swish": convert_swish,
     "tan": convert_unary_op,
     "tanh": convert_unary_op,
+    "top_k_v2": convert_topk,
     "transpose2": convert_transpose,
     "unsqueeze2": convert_unsqueeze,
 }
diff --git a/tests/python/frontend/paddlepaddle/test_forward.py b/tests/python/frontend/paddlepaddle/test_forward.py
index c0e54657a9..de6ea1dcf1 100644
--- a/tests/python/frontend/paddlepaddle/test_forward.py
+++ b/tests/python/frontend/paddlepaddle/test_forward.py
@@ -1351,6 +1351,11 @@ def test_forward_slice():
         x1 = paddle.to_tensor([3]) + paddle.to_tensor([1])
         return inputs[:, x0:, 1:x1, :]
 
+    @paddle.jit.to_static
+    def slice5(inputs):
+        b, c, h, w = inputs  # add decrease_axis
+        return h
+
     input_shape = [1, 3, 10, 10]
     input_data = paddle.rand(input_shape, dtype="float32")
     verify_model(
@@ -1362,6 +1367,7 @@ def test_forward_slice():
     verify_model(slice2, input_data=input_data)
     verify_model(slice3, input_data=paddle.randn((4, 4)))
     verify_model(slice4, input_data=input_data)
+    # verify_model(slice5, input_data=paddle.randn((4,)))
 
 
 @tvm.testing.uses_gpu
@@ -1681,5 +1687,41 @@ def test_forward_rnn():
         )
 
 
+@tvm.testing.uses_gpu
+def test_forward_topk():
+    @paddle.jit.to_static
+    def topk1(inputs):
+        return paddle.topk(inputs, k=1)
+
+    @paddle.jit.to_static
+    def topk2(inputs):
+        k = paddle.to_tensor([1], dtype=paddle.int32)
+        return paddle.topk(inputs, k=k)
+
+    @paddle.jit.to_static
+    def topk3(inputs):
+        return paddle.topk(inputs, k=1, largest=False)
+
+    @paddle.jit.to_static
+    def topk4(inputs):
+        return paddle.topk(inputs, k=2, sorted=True)
+
+    @paddle.jit.to_static
+    def topk5(inputs):
+        return paddle.topk(inputs, k=2, sorted=False)
+
+    @paddle.jit.to_static
+    def topk6(inputs):
+        return paddle.topk(inputs, k=1, axis=0)
+
+    input_data = paddle.to_tensor([[1, 4, 5, 7], [3, 6, 2, 5]], dtype=paddle.int32)
+    verify_model(topk1, input_data=input_data)
+    # verify_model(topk2, input_data=input_data)
+    verify_model(topk3, input_data=input_data)
+    verify_model(topk4, input_data=input_data)
+    verify_model(topk5, input_data=input_data)
+    verify_model(topk6, input_data=input_data)
+
+
 if __name__ == "__main__":
     tvm.testing.main()