From 5992e076102f4b587995bdd488c69312e47ab95b Mon Sep 17 00:00:00 2001 From: wjj19950828 Date: Wed, 8 Sep 2021 21:03:04 +0800 Subject: [PATCH 1/3] Add ops for kunlun --- python/tvm/relay/frontend/paddlepaddle.py | 86 +++++- .../frontend/paddlepaddle/test_forward.py | 245 ++++++++++++++++-- 2 files changed, 305 insertions(+), 26 deletions(-) diff --git a/python/tvm/relay/frontend/paddlepaddle.py b/python/tvm/relay/frontend/paddlepaddle.py index 95d83e6ad67c..bf445e3d7725 100644 --- a/python/tvm/relay/frontend/paddlepaddle.py +++ b/python/tvm/relay/frontend/paddlepaddle.py @@ -484,7 +484,9 @@ def convert_elementwise_op(g, op, block): "elementwise_add": lambda x, y: x + y, "elementwise_mul": lambda x, y: x * y, "elementwise_sub": lambda x, y: x - y, - "elementwise_mod": lambda x, y: x % y, + "elementwise_mod": _op.mod, + "elementwise_pow": _op.power, + "elementwise_floordiv": _op.floor_divide } op_func = op_map[op.type] ipt0 = g.get_node(op.input("X")[0]) @@ -744,6 +746,15 @@ def convert_leaky_relu(g, op, block): g.add_node(op.output("Out")[0], out) +def convert_less_than(g, op, block): + """Operator converter for less_than.""" + + x = g.get_node(op.input("X")[0]) + y = g.get_node(op.input("Y")[0]) + out = _op.less(x, y) + g.add_node(op.output("Out")[0], out) + + def convert_lookup_table(g, op, block): """Operator converter for lookup_table_v2.""" @@ -767,6 +778,20 @@ def convert_log1p(g, op, block): g.add_node(op.output("Out")[0], out) +def convert_logsumexp(g, op, block): + """Operator converter for logsumexp.""" + + input_x = g.get_node(op.input("X")[0]) + axis = op.attr("axis") + if op.attr("reduce_all"): + axis = None + keepdims = op.attr("keepdim") + out = get_relay_op("logsumexp")(input_x, axis=axis, keepdims=keepdims) + if not axis and not keepdims: + out = _op.expand_dims(out, axis=0) + g.add_node(op.output("Out")[0], out) + + def convert_matmul(g, op, block): """Operator converter for matmul.""" @@ -921,6 +946,15 @@ def convert_mul(g, op, block): g.add_node(op.output("Out")[0], out) +def convert_not_equal(g, op, block): + """Operator converter for not_equal.""" + + x = g.get_node(op.input("X")[0]) + y = g.get_node(op.input("Y")[0]) + out = _op.not_equal(x, y) + g.add_node(op.output("Out")[0], out) + + def convert_pool2d(g, op, block): """Operator converter for pool2d.""" @@ -1007,11 +1041,28 @@ def convert_padding(g, op, block): g.add_node(op.output("Out")[0], out) +def convert_pow(g, op, block): + """Operator converter for pow.""" + + x = g.get_node(op.input("X")[0]) + factor = op.attr("factor") + factor = _expr.const(factor, dtype="float32").astype("float32") + + out = _op.power(x, factor) + g.add_node(op.output("Out")[0], out) + + def convert_reduce(g, op, block): """Operator converter for reduce.""" op_map = { "reduce_all": "all", + "reduce_any": "any", + "reduce_max": "max", + "reduce_min": "min", + "reduce_prod": "prod", + "reduce_sum": "sum", + "reduce_mean": "mean", } op_name = op_map[op.type] input_x = g.get_node(op.input("X")[0]) @@ -1286,6 +1337,25 @@ def convert_squeeze(g, op, block): g.add_node(op.output("Out")[0], x) +def convert_topk(g, op, block): + """Operator converter for topk.""" + + x = g.get_node(op.input("X")[0]) + axis = op.attr("axis") + largest = op.attr("largest") + is_ascend = not bool(largest) + k_node = op.input("K") + if k_node: + k_node = g.get_node(k_node[0]) + k = _infer_value(k_node, g.get_params()) + else: + k = op.attr("k") + outs = _op.topk(x, k=k, axis=axis, is_ascend=is_ascend, ret_type="both", dtype="int32") + + g.add_node(op.output("Out")[0], outs[0]) + g.add_node(op.output("Indices")[0], outs[1]) + + def convert_transpose(g, op, block): """Operator converter for transpose.""" @@ -1334,6 +1404,9 @@ def convert_unsqueeze(g, op, block): "elementwise_div": convert_elementwise_op, "elementwise_mul": convert_elementwise_op, "elementwise_sub": convert_elementwise_op, + "elementwise_mod": convert_elementwise_op, + "elementwise_pow": convert_elementwise_op, + "elementwise_floordiv": convert_elementwise_op, "equal": convert_equal, "exp": convert_unary_op, "expand_v2": convert_expand, @@ -1352,20 +1425,30 @@ def convert_unsqueeze(g, op, block): "isinf_v2": convert_unary_op, "layer_norm": convert_layer_norm, "leaky_relu": convert_leaky_relu, + "less_than": convert_less_than, "lookup_table": convert_lookup_table, "lookup_table_v2": convert_lookup_table, "log": convert_unary_op, "log10": convert_unary_op, "log1p": convert_log1p, + "logsumexp": convert_logsumexp, "matmul": convert_matmul, "matmul_v2": convert_matmul, "mul": convert_mul, "nearest_interp_v2": convert_interpolate, + "not_equal": convert_not_equal, "pool2d": convert_pool2d, "pad1d": convert_padding, "pad2d": convert_padding, "pad3d": convert_padding, + "pow": convert_pow, "reduce_all": convert_reduce, + "reduce_any": convert_reduce, + "reduce_max": convert_reduce, + "reduce_min": convert_reduce, + "reduce_prod": convert_reduce, + "reduce_sum": convert_reduce, + "reduce_mean": convert_reduce, "relu": convert_unary_op, "reshape2": convert_reshape, "rnn": convert_rnn, @@ -1378,6 +1461,7 @@ def convert_unsqueeze(g, op, block): "squeeze2": convert_squeeze, "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 eede8a6164ab..635b379e5bf3 100644 --- a/tests/python/frontend/paddlepaddle/test_forward.py +++ b/tests/python/frontend/paddlepaddle/test_forward.py @@ -42,8 +42,8 @@ def assert_shapes_match(tru, est): def get_paddle_model(func, input_spec): global PADDLE_TEST_DATA_ROOT_PATH model_path = Path(PADDLE_TEST_DATA_ROOT_PATH, "model") - paddle.jit.save(func, str(model_path), input_spec=input_spec) + paddle.jit.save(func, "/paddle/pr_for_tvm/0905/tvm/inference_model_test/inference", input_spec=input_spec) baseline_model = paddle.jit.load(str(model_path)) shutil.rmtree(str(PADDLE_TEST_DATA_ROOT_PATH)) @@ -571,6 +571,29 @@ def flatten2(inputs): verify_model(flatten2, input_data=[x_data]) +@tvm.testing.uses_gpu +def test_forward_floor_divide(): + class Floor_divide(nn.Layer): + @paddle.jit.to_static + def forward(self, x, y): + return paddle.floor_divide(x, y) + + x_shape = [10] + y_shape = [10] + x_data = paddle.randint(1, 10, x_shape, dtype="int32") + y_data = paddle.randint(1, 10, y_shape, dtype="int32") + x_data_1 = paddle.randint(1, 10, x_shape, dtype="int64") + y_data_1 = paddle.randint(1, 10, y_shape, dtype="int64") + verify_model(Floor_divide(), input_data=[x_data, y_data]) + verify_model(Floor_divide(), input_data=[x_data_1, y_data_1]) + # For broadcast + x_shape_1 = [10] + y_shape_1 = [10, 1] + x_data_2 = paddle.randint(1, 10, x_shape_1, dtype="int32") + y_data_2 = paddle.randint(1, 10, y_shape_1, dtype="int32") + verify_model(Floor_divide(), input_data=[x_data_2, y_data_2]) + + @tvm.testing.uses_gpu def test_forward_shape_full(): @paddle.jit.to_static @@ -763,6 +786,31 @@ def leaky_relu(inputs): verify_model(leaky_relu, input_data=input_data) +@tvm.testing.uses_gpu +def test_forward_less_than(): + class Less_than(nn.Layer): + @paddle.jit.to_static + def forward(self, x, y): + output = paddle.less_than(x, y) + output = paddle.cast(output, "int32") + return output + + x_shape = [10] + y_shape = [10] + x_data = paddle.randint(1, 10, x_shape, dtype="int32") + y_data = paddle.randint(1, 10, y_shape, dtype="int32") + x_data_1 = paddle.randint(1, 10, x_shape, dtype="int64") + y_data_1 = paddle.randint(1, 10, y_shape, dtype="int64") + verify_model(Less_than(), input_data=[x_data, y_data]) + verify_model(Less_than(), input_data=[x_data_1, y_data_1]) + # For broadcast + x_shape_1 = [10] + y_shape_1 = [10, 1] + x_data_2 = paddle.rand(x_shape_1, dtype="float32") + y_data_2 = paddle.rand(y_shape_1, dtype="float32") + verify_model(Less_than(), input_data=[x_data_2, y_data_2]) + + @tvm.testing.uses_gpu def test_forward_look_up(): @paddle.jit.to_static @@ -855,6 +903,32 @@ def forward(self, input1, input2): verify_model(MatMul1(), input_data=[input_data1, input_data2]) +@tvm.testing.uses_gpu +def test_forward_not_equal(): + class Not_equal(nn.Layer): + @paddle.jit.to_static + def forward(self, x, y): + output = paddle.not_equal(x, y) + output = paddle.cast(output, "int32") + return output + + x_shape = [10] + y_shape = [10] + x_data = paddle.randint(1, 10, x_shape, dtype="int32") + y_data = paddle.randint(1, 10, y_shape, dtype="int32") + x_data_1 = paddle.randint(1, 10, x_shape, dtype="int64") + y_data_1 = paddle.randint(1, 10, y_shape, dtype="int64") + verify_model(Not_equal(), input_data=[x_data, y_data]) + verify_model(Not_equal(), input_data=[x_data_1, y_data_1]) + # For broadcast + x_shape_1 = [10] + y_shape_1 = [10, 1] + x_data_2 = paddle.rand(x_shape_1, dtype="float32") + y_data_2 = paddle.rand(y_shape_1, dtype="float32") + verify_model(Not_equal(), input_data=[x_data_2, y_data_2]) + + + @tvm.testing.uses_gpu def test_forward_pool2d(): @paddle.jit.to_static @@ -916,32 +990,106 @@ def pad4(inputs): @tvm.testing.uses_gpu -def test_forward_reduce(): - @paddle.jit.to_static - def reduce_all(inputs): - inputs = paddle.assign(inputs) - inputs = paddle.cast(inputs, "bool") - inputs = paddle.all(inputs) - return paddle.cast(inputs, "int32") +def test_forward_pow(): + class Pow(nn.Layer): + @paddle.jit.to_static + def forward(self, x): + output = paddle.pow(x, 2) + return output - @paddle.jit.to_static - def reduce_all2(inputs): - inputs = paddle.assign(inputs) - inputs = paddle.cast(inputs, "bool") - inputs = paddle.all(inputs, axis=0) - return paddle.cast(inputs, "int32") + class Pow1(nn.Layer): + @paddle.jit.to_static + def forward(self, x): + output = paddle.pow(x, 2.5) + return output - @paddle.jit.to_static - def reduce_all3(inputs): - inputs = paddle.assign(inputs) - inputs = paddle.cast(inputs, "bool") - inputs = paddle.all(inputs, axis=[0, 1, -1], keepdim=True) - return paddle.cast(inputs, "int32") + class Pow2(nn.Layer): + @paddle.jit.to_static + def forward(self, x, y): + output = paddle.pow(x, y) + return output + + x_data = paddle.to_tensor([1, 2, 3], dtype='float32') + y_data = paddle.to_tensor([2], dtype='float32') + verify_model(Pow(), input_data=[x_data]) + verify_model(Pow1(), input_data=[x_data]) + verify_model(Pow2(), input_data=[x_data, y_data]) + + +@tvm.testing.uses_gpu +def test_forward_reduce_op(): + class ReduceOp_Bool(nn.Layer): + def __init__(self, op_name): + super(ReduceOp_Bool, self).__init__() + self.func = getattr(paddle, op_name, None) + + @paddle.jit.to_static + def forward(self, inputs): + inputs = paddle.cast(inputs, "bool") + output = self.func(inputs) + output = paddle.cast(output, "int32") + return output + + class ReduceOp_Bool1(ReduceOp_Bool): + @paddle.jit.to_static + def forward(self, inputs): + inputs = paddle.cast(inputs, "bool") + output = self.func(inputs, axis=0) + output = paddle.cast(output, "int32") + return output + + class ReduceOp_Bool2(ReduceOp_Bool): + @paddle.jit.to_static + def forward(self, inputs): + inputs = paddle.cast(inputs, "bool") + output = self.func(inputs, axis=[0, 1, -1], keepdim=True) + output = paddle.cast(output, "int32") + return output + + class ReduceOp_Math(nn.Layer): + def __init__(self, op_name): + super(ReduceOp_Math, self).__init__() + self.func = getattr(paddle, op_name, None) + + @paddle.jit.to_static + def forward(self, inputs): + output = self.func(inputs) + return output + + class ReduceOp_Math1(ReduceOp_Math): + @paddle.jit.to_static + def forward(self, inputs): + output = self.func(inputs, axis=0) + return output + + class ReduceOp_Math2(ReduceOp_Math): + @paddle.jit.to_static + def forward(self, inputs): + output = self.func(inputs, axis=[0, 1], keepdim=True) + return output input_data = paddle.randn([1, 2, 3]) - verify_model(reduce_all, input_data=input_data) - verify_model(reduce_all2, input_data=input_data) - verify_model(reduce_all3, input_data=input_data) + op_list_bool = [ + "all", + "any", + ] + for op_name in op_list_bool: + verify_model(ReduceOp_Bool(op_name), input_data) + verify_model(ReduceOp_Bool1(op_name), input_data) + verify_model(ReduceOp_Bool2(op_name), input_data) + input_data1 = paddle.rand([2, 4, 5], dtype="float32") + op_list_math = [ + "max", + "min", + "prod", + "sum", + "mean", + "logsumexp", + ] + for op_name in op_list_math: + verify_model(ReduceOp_Math(op_name), input_data1) + verify_model(ReduceOp_Math1(op_name), input_data1) + verify_model(ReduceOp_Math2(op_name), input_data1) @tvm.testing.uses_gpu @@ -1050,6 +1198,48 @@ def squeeze3(inputs): verify_model(squeeze3, input_data=input_data) +@tvm.testing.uses_gpu +def test_forward_topk(): + class Topk1(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + return paddle.topk(inputs, k=3) + + class Topk2(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + return paddle.topk(inputs, k=3, axis=-2) + + class Topk3(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + return paddle.topk(inputs, k=3, axis=3) + + class Topk4(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + return paddle.topk(inputs, k=3, largest=True) + + class Topk5(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + return paddle.topk(inputs, k=3, largest=False) + + class Topk6(nn.Layer): + @paddle.jit.to_static + def forward(self, inputs): + return paddle.topk(inputs, k=3, sorted=True) + + input_shape = [1, 3, 10, 10] + input_data = paddle.rand(input_shape, dtype="float32") + 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__": test_forward_add_subtract() test_forward_addmm() @@ -1066,6 +1256,7 @@ def squeeze3(inputs): test_forward_dropout() test_forward_expand() test_forward_flatten() + test_forward_floor_divide() test_forward_shape_full() test_forward_ones_like() test_forward_gather_assign_value() @@ -1077,16 +1268,20 @@ def squeeze3(inputs): test_forward_isinf() test_forward_layer_norm() test_forward_leaky_relu() + test_forward_less_than() test_forward_look_up() test_forward_lstm() - test_forward_multiply() test_forward_matmul() + test_forward_multiply() + test_forward_not_equal() test_forward_pool2d() test_forward_pad() - test_forward_reduce() + test_forward_pow() + test_forward_reduce_op() test_forward_reshape() test_forward_scale() test_forward_slice() test_forward_squeeze2() + test_forward_topk() test_forward_conv_transpose() test_forward_unary_op() From 707a9a51390db4b22caeba148fb3e514601a03c8 Mon Sep 17 00:00:00 2001 From: wjj19950828 Date: Wed, 8 Sep 2021 21:15:32 +0800 Subject: [PATCH 2/3] Fixed bugs --- tests/python/frontend/paddlepaddle/test_forward.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/python/frontend/paddlepaddle/test_forward.py b/tests/python/frontend/paddlepaddle/test_forward.py index 635b379e5bf3..962e6cf6abad 100644 --- a/tests/python/frontend/paddlepaddle/test_forward.py +++ b/tests/python/frontend/paddlepaddle/test_forward.py @@ -43,7 +43,6 @@ def get_paddle_model(func, input_spec): global PADDLE_TEST_DATA_ROOT_PATH model_path = Path(PADDLE_TEST_DATA_ROOT_PATH, "model") paddle.jit.save(func, str(model_path), input_spec=input_spec) - paddle.jit.save(func, "/paddle/pr_for_tvm/0905/tvm/inference_model_test/inference", input_spec=input_spec) baseline_model = paddle.jit.load(str(model_path)) shutil.rmtree(str(PADDLE_TEST_DATA_ROOT_PATH)) From 33b050bec29ef3a7ffcce120a4ba25902d743e28 Mon Sep 17 00:00:00 2001 From: wjj19950828 Date: Thu, 9 Sep 2021 14:59:25 +0800 Subject: [PATCH 3/3] Fixed bugs --- python/tvm/relay/frontend/paddlepaddle.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/tvm/relay/frontend/paddlepaddle.py b/python/tvm/relay/frontend/paddlepaddle.py index 684dae767e31..9698f7aa53c8 100644 --- a/python/tvm/relay/frontend/paddlepaddle.py +++ b/python/tvm/relay/frontend/paddlepaddle.py @@ -1049,6 +1049,7 @@ def convert_pow(g, op, block): factor = _expr.const(factor, dtype="float32").astype("float32") out = _op.power(x, factor) + g.add_node(op.output("Out")[0], out) def convert_range(g, op, block):