From 9956e7bd17a3e61435d0f7097c75338eb78bbf5c Mon Sep 17 00:00:00 2001 From: Masahiro Masuda Date: Sat, 9 Oct 2021 04:26:18 +0900 Subject: [PATCH] Revert "[Frontend][PaddlePaddle][Part1] Add 100+ operators for PaddlePaddle (#9126)" This reverts commit c980db393d634572576b34eeddec9cad215c48d5. --- python/tvm/relay/frontend/paddlepaddle.py | 299 +++++------------ .../frontend/paddlepaddle/test_forward.py | 303 +++--------------- 2 files changed, 126 insertions(+), 476 deletions(-) diff --git a/python/tvm/relay/frontend/paddlepaddle.py b/python/tvm/relay/frontend/paddlepaddle.py index 755c9f70f4ab2..76a12691d2bf3 100644 --- a/python/tvm/relay/frontend/paddlepaddle.py +++ b/python/tvm/relay/frontend/paddlepaddle.py @@ -17,6 +17,7 @@ # pylint: disable=invalid-name, import-self, len-as-condition, unused-argument, too-many-lines # pylint: disable=import-outside-toplevel """Paddle: PArallel Distributed Deep LEarning.""" +import warnings import numpy as np @@ -24,171 +25,65 @@ from tvm.ir import IRModule from .. import analysis -from .. import ty as _ty from .. import expr as _expr from .. import function as _function from .. import ty as _ty from .. import op as _op from .common import ( fold_constant, - get_relay_op, infer_shape, infer_type, infer_value, - try_infer_value, new_var, ) __all__ = ["from_paddle"] -def _get_pad_size(in_size, dilated_kernel_size, stride_size): - """Calculate the paddings size for Conv/Pool in SAME padding mode.""" - - if stride_size == 1 or in_size % stride_size == 0: - pad = max(dilated_kernel_size - stride_size, 0) - else: - pad = max(dilated_kernel_size - (in_size % stride_size), 0) - - pad_before = pad // 2 - pad_after = pad - pad_before - - return [pad_before, pad_after] - - -def _dtype_shape_promotion(inputs): - """Promote data type and shape for list of tensors.""" - - dtype_order = ["bool", "int8", "int16", "int32", "int64", "float32", "float64"] - - ranks = [len(infer_shape(x)) for x in inputs] - if set(ranks) == set([1, 0]): - for i, r in enumerate(ranks): - if r == 0: - inputs[i] = _op.expand_dims(inputs[i], axis=0) - - dtypes = set(dtype_order.index(infer_type(x).checked_type.dtype) for x in inputs) - if len(dtypes) == 1: - return inputs - max_dtype = dtype_order[max(dtypes)] - for i, input_op in enumerate(inputs): - if infer_type(input_op).checked_type.dtype != max_dtype: - inputs[i] = input_op.astype(max_dtype) - return inputs - - def shape_of(x, dtype="int32"): - """Get shape of a tensor.""" + """Get shape of a tensor""" ttype = infer_type(x).checked_type if not _ty.is_dynamic(ttype): shape = list(ttype.shape) - return _expr.const(np.array(shape), dtype) + return _expr.const(shape, dtype) return _op.shape_of(x, dtype) -def _convert_dtype_value(val): - """Converts a Paddle type id to a string.""" - - convert_dtype_map = { - 21: "int8", - 20: "uint8", - 6: "float64", - 5: "float32", - 4: "float16", - 3: "int64", - 2: "int32", - 1: "int16", - 0: "bool", - } - if val not in convert_dtype_map: - msg = "Paddle data type value %d is not handled yet." % (val) - raise NotImplementedError(msg) - return convert_dtype_map[val] - - -def convert_unary_op(g, op, block): - """Operator converter for all the unary operators.""" +def _get_pad_size(in_size, dilated_kernel_size, stride_size): + """calculate the paddings size""" - # op_map stores mapping relationship between paddlepaddle and relay - op_map = { - "isinf_v2": _op.isinf, - "isfinite_v2": _op.isfinite, - "isnan_v2": _op.isnan, - } - if op.type in op_map: - unary_func = op_map[op.type] + if stride_size == 1 or in_size % stride_size == 0: + pad = max(dilated_kernel_size - stride_size, 0) else: - # while paddle operator's name is same with relay - unary_func = get_relay_op(op.type) - out = unary_func(g.get_node(op.input("X")[0])) - g.add_node(op.output("Out")[0], out) - + pad = max(dilated_kernel_size - (in_size % stride_size), 0) -def convert_binary_logical_op(g, op, block): - """Operator converter for logical op.""" + pad_before = pad // 2 + pad_after = pad - pad_before - ipt0 = g.get_node(op.input("X")[0]) - ipt1 = g.get_node(op.input("Y")[0]) - op_func = get_relay_op(op.type) - out = op_func(ipt0, ipt1) - g.add_node(op.output("Out")[0], out) + return [pad_before, pad_after] -def convert_arg_max_min(g, op, block): - """Operator converter for arg_max and arg_min.""" +def convert_arg_max(g, op, block): + """Operator converter for arg_max.""" axis = op.attr("axis") keepdims = op.attr("keepdims") flatten = op.attr("flatten") - dtype = op.attr("dtype") - dtype = _convert_dtype_value(dtype) - func = _op.argmax if op.type == "arg_max" else _op.argmin x = g.get_node(op.input("X")[0]) if axis is None or flatten: x = _op.reshape(x, [-1]) - out = func(x, axis=None, keepdims=True) + out = _op.argmax(x, axis=None, keepdims=True) else: - out = func(x, axis=axis, keepdims=keepdims) - if dtype != infer_type(out).checked_type.dtype: - out = _op.cast(out, dtype) - g.add_node(op.output("Out")[0], out) - - -def convert_argsort(g, op, block): - """Operator converter for argsort.""" - - x = g.get_node(op.input("X")[0]) - axis = op.attr("axis") - descending = op.attr("descending") - - out_indices = _op.argsort(x, axis, not descending, dtype="int64") - out = _op.gather(x, axis, out_indices) + out = _op.argmax(x, axis=axis, keepdims=keepdims) g.add_node(op.output("Out")[0], out) - g.add_node(op.output("Indices")[0], out_indices) def convert_assign(g, op, block): """Operator converter for assign.""" - out = g.get_node(op.input("X")[0]) - g.add_node(op.output("Out")[0], out) - - -def convert_assign_value(g, op, block): - """Operator converter for assign_value.""" - - keys = ["bool_values", "fp32_values", "int32_values", "int64_values"] - dtypes = ["bool", "float32", "int32", "int64"] - for i, key in enumerate(keys): - dtype = dtypes[i] - value = np.array(op.attr(key)).astype(dtype) - if value is not None and value.size >= 1: - break - shape = op.attr("shape") - value = value.reshape(shape) - out = _op.const(value, dtype=dtype) + out = _op.copy(g.get_node(op.input("X")[0])) g.add_node(op.output("Out")[0], out) @@ -215,8 +110,8 @@ def convert_batch_norm(g, op, block): def convert_cast(g, op, block): """Operator converter for cast.""" - dtype = op.attr("out_dtype") - dtype = _convert_dtype_value(dtype) + dtype = block.var(op.output("Out")[0]).dtype + dtype = str(dtype).strip().split(".")[1] x = g.get_node(op.input("X")[0]) out = _op.cast(x, dtype=dtype) g.add_node(op.output("Out")[0], out) @@ -227,7 +122,6 @@ def convert_concat(g, op, block): inputs = [g.get_node(op.input("X")[i]) for i in range(len(op.input("X")))] axis = op.attr("axis") - inputs = _dtype_shape_promotion(inputs) out = _op.concatenate(inputs, axis=axis) g.add_node(op.output("Out")[0], out) @@ -244,22 +138,12 @@ def convert_conv2d(g, op, block): kernel = g.get_node(op.input("Filter")[0]) input_x = g.get_node(op.input("Input")[0]) out_channels, _, k_h, k_w = infer_shape(kernel) + in_h, in_w = infer_shape(input_x)[2:] if padding_algorithm == "VALID": paddings = [0, 0] elif padding_algorithm == "SAME": - if strides[0] == 1 and strides[1] == 1: - pad_h = _get_pad_size(0, (k_h - 1) * dilations[0] + 1, strides[0]) - pad_w = _get_pad_size(0, (k_w - 1) * dilations[1] + 1, strides[1]) - else: - input_shape = shape_of(input_x) - h_w = _op.strided_slice(input_shape, [2], [4]) - try: - in_h, in_w = infer_value(h_w, g.get_params()).numpy().tolist() - except Exception as e: - msg = "Dynamic shape is not supported in SAME padding algorithm while stride!=1" - raise tvm.error.OpAttributeInvalid(msg) from e - pad_h = _get_pad_size(in_h, (k_h - 1) * dilations[0] + 1, strides[0]) - pad_w = _get_pad_size(in_w, (k_w - 1) * dilations[1] + 1, strides[1]) + pad_h = _get_pad_size(in_h, (k_h - 1) * dilations[0] + 1, strides[0]) + pad_w = _get_pad_size(in_w, (k_w - 1) * dilations[1] + 1, strides[1]) paddings = [pad_h[0], pad_w[0], pad_h[1], pad_w[1]] elif padding_algorithm == "EXPLICIT": if len(paddings) == 2: @@ -307,18 +191,7 @@ def convert_dropout(g, op, block): """Operator converter for dropout.""" x = g.get_node(op.input("X")[0]) - g.add_node(op.output("Out")[0], x) - - -def convert_dot(g, op, block): - """Operator converter for dot.""" - - # x, y should be 1D or 2D tensor - # when it's 2D tensor, the first dimension means batch dimension - x = g.get_node(op.input("X")[0]) - y = g.get_node(op.input("Y")[0]) - - out = _op.sum(_op.multiply(x, y), axis=[-1], keepdims=True) + out = _op.copy(x) g.add_node(op.output("Out")[0], out) @@ -326,61 +199,49 @@ def convert_elementwise_op(g, op, block): """Operator converter for all the elementwise operators.""" op_map = { - "elementwise_div": "divide", - "elementwise_add": "add", - "elementwise_mul": "multiply", - "elementwise_sub": "subtract", - "elementwise_mod": "mod", - "elementwise_max": "maximum", - "elementwise_min": "minimum", - "elementwise_pow": "power", - "elementwise_floordiv": "floor_divide", - "equal": "equal", - "greater_equal": "greater_equal", - "greater_than": "greater", - "less_equal": "less_equal", - "less_than": "less", - "not_equal": "not_equal", + "elementwise_div": lambda x, y: x / y, + "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, } op_func = op_map[op.type] ipt0 = g.get_node(op.input("X")[0]) ipt1 = g.get_node(op.input("Y")[0]) - ipt0_shape = infer_shape(ipt0) - ipt1_shape = infer_shape(ipt1) + ipt0_shape = block.var(op.input("X")[0]).shape + ipt1_shape = block.var(op.input("Y")[0]).shape axis = op.attr("axis") if len(ipt0_shape) != len(ipt1_shape): if axis < 0: axis = axis + len(ipt0_shape) if axis != len(ipt0_shape) - 1: ipt1 = _op.expand_dims(ipt1, axis=axis, num_newaxis=(len(ipt0_shape) - axis - 1)) - op_func = get_relay_op(op_func) out = op_func(ipt0, ipt1) g.add_node(op.output("Out")[0], out) -def convert_expand(g, op, block): - """Operator converter for expand.""" +def convert_equal(g, op, block): + """Operator converter for equal.""" x = g.get_node(op.input("X")[0]) - if op.input("Shape"): - sizes = g.get_node(op.input("Shape")[0]) - sizes = try_infer_value(sizes, g.get_params())[0] - else: - sizes = op.attr("shape") - - if isinstance(sizes, np.ndarray): - sizes = sizes.tolist() - - out = _op.broadcast_to(x, sizes) + y = g.get_node(op.input("Y")[0]) + out = _op.equal(x, y) g.add_node(op.output("Out")[0], out) -def convert_expand_as(g, op, block): - """Operator converter for expand_as.""" +def convert_activation(g, op, block): + """Operator converter for all the activation.""" - x = g.get_node(op.input("X")[0]) - target_shape = op.attr("target_shape") - out = _op.broadcast_to(x, target_shape) + op_map = { + "exp": _op.exp, + "relu": _op.nn.relu, + "tanh": _op.tanh, + "sqrt": _op.sqrt, + "erf": _op.erf, + "abs": _op.abs, + } + act_func = op_map[op.type] + out = act_func(g.get_node(op.input("X")[0])) g.add_node(op.output("Out")[0], out) @@ -389,20 +250,15 @@ def convert_feed(g, op, block): if block is not None: ipt_name = op.output("Out")[0] - dtype = op.attr("dtype") - dtype = _convert_dtype_value(dtype) + ipt_shape = block.var(ipt_name).shape + ipt_dtype = block.var(ipt_name).dtype + ipt_dtype = str(ipt_dtype).strip().split(".")[1] else: ipt_shape = op.shape ipt_dtype = str(op.dtype).strip().split(".")[1] ipt_name = op.name if g.shape_dict is not None: ipt_shape = g.shape_dict[ipt_name] - - if isinstance(ipt_shape, tuple): - ipt_shape = list(ipt_shape) - for i, s in enumerate(ipt_shape): - if s < 0: - ipt_shape[i] = _ty.Any() out = new_var(ipt_name, shape=ipt_shape, dtype=ipt_dtype) g.add_node(ipt_name, out) @@ -410,11 +266,18 @@ def convert_feed(g, op, block): def convert_fill_any_like(g, op, block): """Operator converter for fill_any_like.""" - dtype = op.attr("dtype") - dtype = _convert_dtype_value(dtype) + out_name = op.output("Out")[0] + out_dtype = block.var(out_name).dtype + out_dtype = str(out_dtype).strip().split(".")[1] x = g.get_node(op.input("X")[0]) - value = _expr.const(op.attr("value"), dtype=dtype) - out = _op.transform.full_like(x, value).astype(dtype) + ipt_type = infer_type(x).checked_type + value = op.attr("value") + if not _ty.is_dynamic(ipt_type): + shape = infer_shape(x) + const = np.ones(shape) * value + out = _expr.const(const.astype(out_dtype)) + else: + out = _op.transform.full_like(x, value).astype(out_dtype) g.add_node(op.output("Out")[0], out) @@ -423,20 +286,16 @@ def convert_fill_constant(g, op, block): value = op.attr("value") shape = block.var(op.output("Out")[0]).shape - dtype = op.attr("dtype") - dtype = _convert_dtype_value(dtype) - value = _expr.const(value).astype(dtype) - if "ValueTensor" in op.input_names and op.input("ValueTensor"): + dtype = block.var(op.output("Out")[0]).dtype + dtype = str(dtype).strip().split(".")[1] + if op.input("ValueTensor"): shape = g.get_node(op.input("ValueTensor")[0]) - shape = try_infer_value(shape, g.get_params())[0] - if "ShapeTensor" in op.input_names and op.input("ShapeTensor"): + shape = infer_value(shape, g.get_params()).numpy() + if op.input("ShapeTensor"): shape = g.get_node(op.input("ShapeTensor")[0]) - shape = try_infer_value(shape, g.get_params())[0] - - if isinstance(shape, np.ndarray): - shape = shape.tolist() - - out = _op.full(value, shape=shape, dtype=dtype) + shape = infer_value(shape, g.get_params()).numpy() + value = np.full(shape, value, dtype) + out = _expr.const(value.astype(dtype)).astype(dtype) g.add_node(op.output("Out")[0], out) @@ -863,53 +722,41 @@ def convert_unsqueeze(g, op, block): _convert_map = { - "arg_max": convert_arg_max_min, - "arg_min": convert_arg_max_min, - "argsort": convert_argsort, + "arg_max": convert_arg_max, "assign": convert_assign, - "assign_value": convert_assign_value, "batch_norm": convert_batch_norm, "cast": convert_cast, "concat": convert_concat, "conv2d": convert_conv2d, "cumsum": convert_cumsum, "depthwise_conv2d": convert_conv2d, - "dot": convert_dot, "dropout": convert_dropout, "elementwise_add": convert_elementwise_op, "elementwise_div": convert_elementwise_op, "elementwise_mul": convert_elementwise_op, "elementwise_sub": convert_elementwise_op, - "equal": convert_elementwise_op, - "exp": convert_unary_op, - "expand_v2": convert_expand, - "expand_as_v2": convert_expand_as, + "equal": convert_equal, + "exp": convert_activation, "feed": convert_feed, "fill_any_like": convert_fill_any_like, "fill_constant": convert_fill_constant, "gelu": convert_gelu, "hard_sigmoid": convert_hard_sigmoid, "hard_swish": convert_hard_swish, - "isfinite_v2": convert_unary_op, - "isinf_v2": convert_unary_op, - "isnan_v2": convert_unary_op, "layer_norm": convert_layer_norm, "leaky_relu": convert_leaky_relu, - "logical_and": convert_binary_logical_op, - "logical_or": convert_binary_logical_op, - "logical_xor": convert_binary_logical_op, "lookup_table_v2": convert_lookup_table, "matmul": convert_matmul, "matmul_v2": convert_matmul, "mul": convert_mul, "pool2d": convert_pool2d, - "relu": convert_unary_op, + "relu": convert_activation, "reshape2": convert_reshape, "scale": convert_scale, "shape": convert_shape, "slice": convert_slice, "softmax": convert_softmax, - "tanh": convert_unary_op, + "tanh": convert_activation, "unsqueeze2": convert_unsqueeze, } @@ -934,7 +781,7 @@ def add_node(self, name, node): self.nodes[name] = fold_constant(node) def get_params(self, name=None): - """Get params from graph.""" + """get params from graph""" if name is None: return self.params diff --git a/tests/python/frontend/paddlepaddle/test_forward.py b/tests/python/frontend/paddlepaddle/test_forward.py index 1d64f947e68a9..db07e07f9d83c 100644 --- a/tests/python/frontend/paddlepaddle/test_forward.py +++ b/tests/python/frontend/paddlepaddle/test_forward.py @@ -24,7 +24,6 @@ import tvm.topi.testing from tvm import relay from tvm.contrib import graph_executor -import pytest import paddle import paddle.nn as nn @@ -83,9 +82,8 @@ def verify_model(func, input_data, rtol=1e-5, atol=1e-5): parms_num = min(len(input_names), len(mod["main"].params)) compiled_names = [] for arg in mod["main"].params[:parms_num]: - assert arg.name_hint in input_names or arg.name_hint in params - if arg.name_hint in input_names: - compiled_names.append(arg.name_hint) + assert arg.name_hint in input_names + compiled_names.append(arg.name_hint) with tvm.transform.PassContext(opt_level=3): for target, dev in tvm.testing.enabled_targets(): @@ -127,7 +125,9 @@ def add_subtract3(inputs1, inputs2): @tvm.testing.uses_gpu -def test_forward_arg_max_min(): +def test_forward_argmax(): + input_shape = [1, 3, 10, 10] + class ArgMax(nn.Layer): @paddle.jit.to_static def forward(self, inputs): @@ -148,70 +148,11 @@ class ArgMax3(nn.Layer): def forward(self, inputs): return inputs.argmax(axis=2, keepdim=True) - class ArgMin(nn.Layer): - @paddle.jit.to_static - def forward(self, inputs): - return paddle.argmin(inputs) - - class ArgMin1(nn.Layer): - @paddle.jit.to_static - def forward(self, inputs): - return inputs.argmin(axis=1) - - class ArgMin2(nn.Layer): - @paddle.jit.to_static - def forward(self, inputs): - return inputs.argmax(axis=1, keepdim=False) - - class ArgMin3(nn.Layer): - @paddle.jit.to_static - def forward(self, inputs): - return inputs.argmin(axis=2, keepdim=True) - - input_shapes = [[256], [5, 28], [10, 5, 4], [1, 3, 8, 8]] - for input_shape in input_shapes: - input_data = paddle.rand(input_shape, dtype="float32") - verify_model(ArgMax(), input_data=input_data) - verify_model(ArgMin(), input_data=input_data) - for input_shape in input_shapes[1:]: - input_data = paddle.rand(input_shape, dtype="float32") - verify_model(ArgMax1(), input_data=input_data) - verify_model(ArgMax2(), input_data=input_data) - verify_model(ArgMin1(), input_data=input_data) - verify_model(ArgMin2(), input_data=input_data) - for input_shape in input_shapes[2:]: - input_data = paddle.rand(input_shape, dtype="float32") - verify_model(ArgMax3(), input_data=input_data) - verify_model(ArgMin3(), input_data=input_data) - - -@tvm.testing.uses_gpu -def test_forward_argsort(): - class ArgSort1(nn.Layer): - @paddle.jit.to_static - def forward(self, inputs): - return paddle.argsort(inputs) - - class ArgSort2(nn.Layer): - @paddle.jit.to_static - def forward(self, inputs): - return paddle.argsort(inputs, axis=0, descending=True) - - class ArgSort3(nn.Layer): - @paddle.jit.to_static - def forward(self, inputs): - return paddle.argsort(inputs, axis=-1, descending=True) - - input_shapes = [[256], [10, 20], [10, 5, 3], [1, 3, 5, 5]] - for input_shape in input_shapes: - # Avoid duplicate elements in the array which will bring - # different results with different sort algorithms - np.random.seed(13) - np_data = np.random.choice(range(-5000, 5000), np.prod(input_shape), replace=False) - input_data = paddle.to_tensor(np_data.reshape(input_shape).astype("int64")) - verify_model(ArgSort1(), [input_data]) - verify_model(ArgSort2(), [input_data]) - verify_model(ArgSort3(), [input_data]) + input_data = paddle.rand(input_shape, dtype="float32") + verify_model(ArgMax(), input_data=input_data) + verify_model(ArgMax1(), input_data=input_data) + verify_model(ArgMax2(), input_data=input_data) + verify_model(ArgMax3(), input_data=input_data) @tvm.testing.uses_gpu @@ -220,11 +161,6 @@ def test_forward_assign(): def assign(inputs): return paddle.assign(inputs) - @paddle.jit.to_static - def assign_value(inputs): - x = paddle.to_tensor(np.array([3]).astype("float32")) - return inputs + x - input_shape = [2, 3] input_data = paddle.rand(input_shape, dtype="float32") verify_model( @@ -240,7 +176,6 @@ def assign_value(inputs): input_data2, ], ) - verify_model(assign_value, [input_data]) @tvm.testing.uses_gpu @@ -306,31 +241,6 @@ def cast2(inputs, dtype="int64"): ) -@tvm.testing.uses_gpu -def test_forward_check_tensor(): - class IsFinite(nn.Layer): - @paddle.jit.to_static - def forward(self, inputs): - return paddle.cast(paddle.isfinite(inputs), "int32") - - class IsNan(nn.Layer): - @paddle.jit.to_static - def forward(self, inputs): - return paddle.cast(paddle.isnan(inputs), "int32") - - class IsInf(nn.Layer): - @paddle.jit.to_static - def forward(self, inputs): - return paddle.cast(paddle.isinf(inputs), "int32") - - input_shapes = [[32], [8, 32], [2, 5, 20], [2, 3, 8, 8], [2, 2, 3, 6, 6]] - for input_shape in input_shapes: - input_data = paddle.rand(input_shape, dtype="float32") - verify_model(IsFinite(), input_data=input_data) - verify_model(IsNan(), input_data=input_data) - verify_model(IsInf(), input_data=input_data) - - @tvm.testing.uses_gpu def test_forward_concat_unsqueeze(): @paddle.jit.to_static @@ -410,20 +320,6 @@ def forward(self, inputs): verify_model(Conv2D2(), input_data=conv2d_input_data) -@tvm.testing.uses_gpu -def test_forward_dot(): - class Dot(nn.Layer): - @paddle.jit.to_static - def forward(self, x, y): - return paddle.dot(x, y) - - input_shapes = [[128], [8, 24]] - for input_shape in input_shapes: - x_data = paddle.rand(input_shape, dtype="float32") - y_data = paddle.rand(input_shape, dtype="float32") - verify_model(Dot(), input_data=[x_data, y_data]) - - @tvm.testing.uses_gpu def test_forward_dropout(): @paddle.jit.to_static @@ -436,93 +332,6 @@ def dropout(inputs): verify_model(dropout, input_data=input_data) -def test_forward_elemwise(): - class ElemwiseAPI(nn.Layer): - def __init__(self, api_name): - super(ElemwiseAPI, self).__init__() - self.api_name_ = api_name - for candidate in (paddle, paddle.nn.functional): - self.func = getattr(candidate, api_name, None) - if self.func: - break - - @paddle.jit.to_static - def forward(self, input1, input2): - y = self.func(input1, input2) - if "equal" in self.api_name_ or "than" in self.api_name_: - # for compare operation, cast boolean result to int32 - y = paddle.cast(y, "int32") - return y - - api_list = [ - "equal", - ] - x_shapes = [[128], [8, 20], [4, 20, 3], [2, 3, 8, 8], [2, 3, 3, 9, 9]] - y_shapes = [[1], [8, 20], [4, 1, 1], [2, 3, 8, 8], [2, 3, 3, 9, 1]] - for x_shape, y_shape in zip(x_shapes, y_shapes): - x_data = paddle.randint(1, 1000, x_shape, dtype="int32") - y_data = paddle.randint(1, 1000, y_shape, dtype="int32") - for api_name in api_list: - verify_model(ElemwiseAPI(api_name), [x_data, y_data]) - - -@tvm.testing.uses_gpu -def test_forward_expand(): - @paddle.jit.to_static - def expand1(inputs): - return paddle.expand(inputs, shape=[2, 128]) - - @paddle.jit.to_static - def expand2(inputs): - return paddle.expand(inputs, shape=[2, 1, 4, 16]) - - @paddle.jit.to_static - def expand3(inputs): - return paddle.expand(inputs, shape=[2, 1, 3, 7, 7]) - - @paddle.jit.to_static - def expand4(inputs): - shape = paddle.to_tensor(np.array([2, 128]).astype("int32")) - return paddle.expand(inputs, shape=shape) - - @paddle.jit.to_static - def expand5(inputs): - shape = paddle.to_tensor(np.array([2, 1, 4, 16]).astype("int32")) - return paddle.expand(inputs, shape=shape) - - @paddle.jit.to_static - def expand6(inputs): - shape = paddle.to_tensor(np.array([2, 1, 3, 7, 7]).astype("int32")) - return paddle.expand(inputs, shape=shape) - - data = paddle.rand([128], dtype="float32") - verify_model(expand1, input_data=[data]) - verify_model(expand4, input_data=[data]) - data = paddle.rand([4, 16], dtype="float32") - verify_model(expand2, input_data=[data]) - verify_model(expand5, input_data=[data]) - data = paddle.rand([1, 3, 7, 7], dtype="float32") - verify_model(expand3, input_data=[data]) - verify_model(expand6, input_data=[data]) - - -@tvm.testing.uses_gpu -def test_forward_expand_as(): - class ExpandAs(nn.Layer): - @paddle.jit.to_static - def forward(self, x, y): - z = paddle.expand_as(x, y) - z += y - return z - - x_shapes = [[1], [8, 128], [8, 1, 1], [2, 3, 229, 229], [2, 3, 3, 224, 1]] - y_shapes = [[128], [8, 128], [8, 200, 300], [2, 3, 229, 229], [2, 3, 3, 224, 224]] - for x_shape, y_shape in zip(x_shapes, y_shapes): - x_data = paddle.rand(x_shape, dtype="float32") - y_data = paddle.rand(y_shape, dtype="float32") - verify_model(ExpandAs(), [x_data, y_data]) - - @tvm.testing.uses_gpu def test_forward_shape_full(): @paddle.jit.to_static @@ -623,32 +432,6 @@ def leaky_relu(inputs): verify_model(leaky_relu, input_data=input_data) -@tvm.testing.uses_gpu -def test_forward_logical_api(): - class LogicalAPI(nn.Layer): - def __init__(self, api_name): - super(LogicalAPI, self).__init__() - for candidate in (paddle, paddle.nn.functional): - self.func = getattr(candidate, api_name, None) - if self.func: - break - - @paddle.jit.to_static - def forward(self, x, y): - out = paddle.to_tensor([True, True, True]) - z = self.func(x, y, out=out) - return paddle.cast(z, "int32") - - x_shapes = [[128], [8, 20], [4, 20, 3], [2, 3, 8, 8], [2, 3, 3, 9, 9]] - y_shapes = [[1], [8, 20], [4, 1, 1], [2, 3, 8, 8], [2, 3, 3, 9, 1]] - for x_shape, y_shape in zip(x_shapes, y_shapes): - x_data = paddle.randint(0, 2, x_shape).astype("bool") - y_data = paddle.randint(0, 2, y_shape).astype("bool") - verify_model(LogicalAPI("logical_and"), [x_data, y_data]) - verify_model(LogicalAPI("logical_or"), [x_data, y_data]) - verify_model(LogicalAPI("logical_xor"), [x_data, y_data]) - - @tvm.testing.uses_gpu def test_forward_look_up(): @paddle.jit.to_static @@ -743,6 +526,17 @@ def pool2d3(inputs): # verify_model(pool2d3, input_data=input_data) +@tvm.testing.uses_gpu +def test_forward_relu(): + @paddle.jit.to_static + def relu(inputs): + return nn.functional.relu(inputs) + + input_shape = [10, 10] + input_data = paddle.rand(input_shape, dtype="float32") + verify_model(relu, input_data=input_data) + + @tvm.testing.uses_gpu def test_forward_reshape(): @paddle.jit.to_static @@ -829,30 +623,39 @@ def slice4(inputs): @tvm.testing.uses_gpu -def test_forward_math_api(): - class MathAPI(nn.Layer): - def __init__(self, api_name): - super(MathAPI, self).__init__() - for candidate in (paddle, paddle.nn.functional): - self.func = getattr(candidate, api_name, None) - if self.func: - break - - @paddle.jit.to_static - def forward(self, inputs): - return self.func(inputs) +def test_forward_tanh(): + @paddle.jit.to_static + def tanh(inputs): + return paddle.tanh(inputs) - api_list = [ - "exp", - "relu", - "tanh", - ] - input_shapes = [[128], [2, 100], [10, 2, 5], [7, 3, 4, 1]] - for input_shape in input_shapes: - input_data = paddle.rand(input_shape, dtype="float32") - for api_name in api_list: - verify_model(MathAPI(api_name), input_data=input_data) + input_shape = [1, 3, 10, 10] + input_data = paddle.rand(input_shape, dtype="float32") + verify_model(tanh, input_data=input_data) if __name__ == "__main__": - pytest.main([__file__]) + test_forward_add_subtract() + test_forward_argmax() + test_forward_assign() + test_forward_batch_norm() + test_forward_cast() + test_forward_concat_unsqueeze() + test_forward_cumsum() + test_forward_conv() + test_forward_dropout() + test_forward_shape_full() + test_forward_ones_like() + test_forward_gelu() + test_forward_hard_sigmoid() + test_forward_hard_swish() + test_forward_layer_norm() + test_forward_leaky_relu() + test_forward_look_up() + test_forward_multiply() + test_forward_matmul() + test_forward_pool2d() + test_forward_relu() + test_forward_reshape() + test_forward_scale() + test_forward_slice() + test_forward_tanh()