diff --git a/python/tvm/relay/frontend/paddlepaddle.py b/python/tvm/relay/frontend/paddlepaddle.py index 78895e4b49e0..4b849987ed81 100755 --- a/python/tvm/relay/frontend/paddlepaddle.py +++ b/python/tvm/relay/frontend/paddlepaddle.py @@ -1084,6 +1084,19 @@ def convert_meshgrid(g, op, block): g.add_node(op.output("Out")[i], out) +def convert_mish(g, op, block): + """Operator converter for mish.""" + + x = g.get_node(op.input("X")[0]) + dtype = infer_type(x).checked_type.dtype + exp = _op.exp(x) + add = _op.add(exp, _expr.const(1.0, dtype)) + log = _op.log(add) + tanh = _op.tanh(log) + out = _op.multiply(x, tanh) + g.add_node(op.output("Out")[0], out) + + def convert_mul(g, op, block): """Operator converter for mul.""" @@ -1785,6 +1798,14 @@ def convert_shape(g, op, block): g.add_node(op.output("Out")[0], out) +def convert_silu(g, op, block): + """Operator converter for silu.""" + + x = g.get_node(op.input("X")[0]) + out = _op.multiply(x, _op.sigmoid(x)) + g.add_node(op.output("Out")[0], out) + + def convert_size(g, op, block): """Operator converter for size.""" @@ -1950,6 +1971,19 @@ def convert_softsign(g, op, block): g.add_node(op.output("Out")[0], out) +def convert_softshrink(g, op, block): + """Operator converter for softshrink.""" + + x = g.get_node(op.input("X")[0]) + dtype = infer_type(x).checked_type.dtype + threshold = _expr.const(op.attr("lambda"), dtype=dtype) + zeros = _op.zeros_like(x) + out = _op.where(x < -threshold, x + threshold, zeros) + _op.where( + x > threshold, x - threshold, zeros + ) + g.add_node(op.output("Out")[0], out) + + def convert_split(g, op, block): """Operator converter for split.""" @@ -1994,6 +2028,18 @@ def convert_split(g, op, block): g.add_node(op.output("Out")[i], out_i) +def convert_stack(g, op, blcok): + """Operator converter for stack.""" + + x = op.input("X") + all_inputs = [] + for inp in x: + all_inputs.append(g.get_node(inp)) + axis = op.attr("axis") + out = _op.stack(all_inputs, axis) + g.add_node(op.output("Y")[0], out) + + def convert_square(g, op, block): """Operator converter for square.""" @@ -2025,6 +2071,37 @@ def convert_swish(g, op, block): g.add_node(op.output("Out")[0], out) +def convert_tile(g, op, block): + """Operator converter for tile.""" + + x = g.get_node(op.input("X")[0]) + if op.input("RepeatTimes"): + reps = g.get_node(op.input("RepeatTimes")[0]) + reps, infered = try_infer_value(reps, g.get_params()) + if infered: + reps = reps.tolist() + elif op.input("repeat_times_tensor"): + reps = [] + for rep_value in op.input("repeat_times_tensor"): + rep_value = g.get_node(rep_value).astype("int32") + reps.append(rep_value) + reps = _op.concatenate(reps, axis=0) + reps, infered = try_infer_value(reps, g.get_params()) + if infered: + reps = reps.tolist() + else: + reps = op.attr("repeat_times") + infered = True + + if not infered: + msg = 'Value {} in attribute "repeat_times" of operator Tile is not "valid."' + raise tvm.error.OpAttributeInvalid(msg.format(reps)) + + op_func = get_relay_op(op.type) + out = op_func(x, reps=reps) + g.add_node(op.output("Out")[0], out) + + def convert_topk(g, op, block): """Operator converter for topk.""" @@ -2074,6 +2151,28 @@ def convert_unsqueeze(g, op, block): g.add_node(op.output("Out")[0], x) +def convert_unstack(g, op, block): + """Operator converter for unstack.""" + + x = g.get_node(op.input("X")[0]) + axis = op.attr("axis") + indices_or_sections = len(op.output("Y")) + outs = _op.split(x, indices_or_sections=indices_or_sections, axis=axis) + for i, out in enumerate(outs): + out = _op.squeeze(out, axis=axis) + g.add_node(op.output("Y")[i], out) + + +def convert_where(g, op, block): + """Operator converter for where.""" + + condition = g.get_node(op.input("Condition")[0]) + x = g.get_node(op.input("X")[0]) + y = g.get_node(op.input("Y")[0]) + out = _op.where(condition, x, y) + g.add_node(op.output("Out")[0], out) + + def convert_where_index(g, op, block): """Operator converter for where_index.""" @@ -2166,6 +2265,7 @@ def convert_where_index(g, op, block): "matmul": convert_matmul, "matmul_v2": convert_matmul, "meshgrid": convert_meshgrid, + "mish": convert_mish, "mul": convert_mul, "mv": convert_mv, "nearest_interp_v2": convert_interpolate, @@ -2201,6 +2301,7 @@ def convert_where_index(g, op, block): "shape": convert_shape, "sigmoid": convert_unary_op, "sign": convert_unary_op, + "silu": convert_silu, "sin": convert_unary_op, "sinh": convert_unary_op, "size": convert_size, @@ -2208,7 +2309,9 @@ def convert_where_index(g, op, block): "softmax": convert_softmax, "softplus": convert_softplus, "softsign": convert_softsign, + "softshrink": convert_softshrink, "split": convert_split, + "stack": convert_stack, "strided_slice": convert_slice, "sqrt": convert_unary_op, "square": convert_square, @@ -2216,9 +2319,12 @@ def convert_where_index(g, op, block): "swish": convert_swish, "tan": convert_unary_op, "tanh": convert_unary_op, + "tile": convert_tile, "top_k_v2": convert_topk, "transpose2": convert_transpose, "unsqueeze2": convert_unsqueeze, + "unstack": convert_unstack, + "where": convert_where, "where_index": convert_where_index, } diff --git a/tests/python/frontend/paddlepaddle/test_forward.py b/tests/python/frontend/paddlepaddle/test_forward.py index 70fbf6aee554..4a34498556df 100755 --- a/tests/python/frontend/paddlepaddle/test_forward.py +++ b/tests/python/frontend/paddlepaddle/test_forward.py @@ -1784,5 +1784,191 @@ def where_index_1(inputs): verify_model(where_index_1, input_data=input_data, use_vm=True) +@tvm.testing.uses_gpu +def test_forward_stack(): + class Stack1(nn.Layer): + @paddle.jit.to_static + def forward(self, input0, input1, input2): + return paddle.stack([input0, input1, input2], axis=-1) + + class Stack2(nn.Layer): + @paddle.jit.to_static + def forward(self, input0, input1, input2): + return paddle.stack([input0, input1, input2], axis=1) + + class Stack3(nn.Layer): + @paddle.jit.to_static + def forward(self, input0, input1, input2): + return paddle.stack([input0, input1, input2], axis=2) + + input_shapes = [[2, 3], [5, 10, 11], [3, 4, 5, 6]] + for input_shape in input_shapes: + input_data_0 = paddle.randn(shape=input_shape, dtype="float32") + input_data_1 = paddle.randn(shape=input_shape, dtype="float32") + input_data_2 = paddle.randn(shape=input_shape, dtype="float32") + verify_model(Stack1(), [input_data_0, input_data_1, input_data_2]) + verify_model(Stack2(), [input_data_0, input_data_1, input_data_2]) + verify_model(Stack3(), [input_data_0, input_data_1, input_data_2]) + + +@tvm.testing.uses_gpu +def test_forward_unstack(): + class UnStack1(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + return paddle.unstack(inputs, axis=-1) + + class UnStack2(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + return paddle.unstack(inputs, axis=1) + + class UnStack3(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + return paddle.unstack(inputs, axis=0) + + input_shapes = [[2, 3], [5, 10, 11], [3, 4, 5, 6], [1, 3, 4, 1, 1]] + for input_shape in input_shapes: + input_data = paddle.randn(shape=input_shape, dtype="float32") + verify_model(UnStack1(), input_data) + verify_model(UnStack2(), input_data) + verify_model(UnStack3(), input_data) + + +@tvm.testing.uses_gpu +def test_forward_silu(): + class Silu(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + return nn.functional.silu(inputs) + + input_shapes = [[10], [2, 3], [5, 10, 11], [3, 4, 5, 6]] + for input_shape in input_shapes: + input_data = paddle.randn(shape=input_shape, dtype="float32") + verify_model(Silu(), input_data=input_data) + + +@tvm.testing.uses_gpu +def test_forward_softshrink(): + @paddle.jit.to_static + def Softshrink1(input): + return nn.functional.softshrink(input, threshold=0.0) + + @paddle.jit.to_static + def Softshrink2(input): + return nn.functional.softshrink(input, threshold=0.5) + + @paddle.jit.to_static + def Softshrink3(input): + return nn.functional.softshrink(input, threshold=1.0) + + x = paddle.to_tensor([-0.9, -0.2, 0.1, 0.8]) + verify_model(Softshrink2, x) + + input_shapes = [[10], [2, 3], [5, 10, 11], [3, 4, 5, 6]] + for input_shape in input_shapes: + input_data = paddle.randn(shape=input_shape, dtype="float32") + verify_model(Softshrink1, input_data=input_data) + verify_model(Softshrink2, input_data=input_data) + verify_model(Softshrink3, input_data=input_data) + + +@tvm.testing.uses_gpu +def test_forward_where(): + @paddle.jit.to_static + def where1(x, y): + return paddle.where(x > 1, x, y) + + @paddle.jit.to_static + def where2(x, y): + return paddle.where(x > y, x, y) + + x = paddle.to_tensor([0.9383, 0.1983, 3.2, 1.2]) + y = paddle.to_tensor([1.0, 1.0, 1.0, 1.0]) + verify_model(where1, [x, y]) + + input_shapes = [[10], [2, 3], [5, 10, 11], [3, 4, 5, 6]] + for input_shape in input_shapes: + x = paddle.randn(shape=input_shape, dtype="float32") + y = paddle.randn(shape=input_shape, dtype="float32") + verify_model(where1, [x, y]) + verify_model(where2, [x, y]) + + +@tvm.testing.uses_gpu +def test_forward_tile(): + class Tile1(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + return paddle.tile(inputs, repeat_times=[10]) + + class Tile2(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + return paddle.tile(inputs, repeat_times=[2, 3]) + + class Tile3(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + return paddle.tile(inputs, repeat_times=[1, 2, 3]) + + class Tile4(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + return paddle.tile(inputs, repeat_times=[2, 3, 4, 1, 5]) + + class Tile5(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + reps = paddle.to_tensor([3, 2]) + reps = paddle.cast(reps, "int32") + return paddle.tile(inputs, repeat_times=reps) + + class Tile6(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + rep_0 = paddle.to_tensor([3]) + rep_1 = paddle.to_tensor([2]) + rep_0 = paddle.cast(rep_0, "int32") + rep_1 = paddle.cast(rep_1, "int32") + return paddle.tile(inputs, repeat_times=[rep_0, rep_1]) + + input_shapes = [ + [10], + [2, 3], + [3, 4, 5], + [5, 3, 1, 4], + [1, 3, 1, 6, 7], + ] + for input_shape in input_shapes: + input_data = paddle.randn(shape=input_shape, dtype="float32") + verify_model(Tile1(), input_data=input_data) + verify_model(Tile2(), input_data=input_data) + verify_model(Tile3(), input_data=input_data) + verify_model(Tile4(), input_data=input_data) + verify_model(Tile5(), input_data=input_data) + verify_model(Tile6(), input_data=input_data) + + +@tvm.testing.uses_gpu +def test_forward_mish(): + class Mish(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + return nn.functional.mish(inputs) + + input_shapes = [[10], [2, 3], [5, 10, 11], [3, 4, 5, 6]] + if paddle.version.full_version >= "2.4.2": + for input_shape in input_shapes: + input_data = paddle.randn(shape=input_shape, dtype="float32") + verify_model(Mish(), input_data=input_data) + input_data += 20.0 + verify_model(Mish(), input_data=input_data) + + input_data = paddle.to_tensor([-5.0, 0.0, 5.0, 23.1, 20.0]) + verify_model(Mish(), input_data=input_data) + + if __name__ == "__main__": tvm.testing.main()