664 lines
20 KiB
Python
664 lines
20 KiB
Python
# Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import unittest
|
|
|
|
import gradient_checker
|
|
import numpy as np
|
|
from decorator_helper import prog_scope
|
|
from op_test import (
|
|
OpTest,
|
|
convert_float_to_uint16,
|
|
get_device_place,
|
|
get_places,
|
|
is_custom_device,
|
|
)
|
|
|
|
import paddle
|
|
from paddle import base
|
|
from paddle.base import core
|
|
|
|
|
|
# Situation 1: repeat_times is a list (without tensor)
|
|
class TestTileOpRank1(OpTest):
|
|
def setUp(self):
|
|
self.op_type = "tile"
|
|
self.python_api = paddle.tile
|
|
self.prim_op_type = "prim"
|
|
self.public_python_api = paddle.tile
|
|
self.init_data()
|
|
self.if_enable_cinn()
|
|
|
|
self.inputs = {'X': np.random.random(self.ori_shape).astype("float64")}
|
|
self.attrs = {'repeat_times': self.repeat_times}
|
|
output = np.tile(self.inputs['X'], self.repeat_times)
|
|
self.outputs = {'Out': output}
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = True
|
|
|
|
def init_data(self):
|
|
self.ori_shape = [100]
|
|
self.repeat_times = [2]
|
|
|
|
def test_check_output(self):
|
|
self.check_output(
|
|
check_cinn=self.check_cinn, check_pir=True, check_prim_pir=True
|
|
)
|
|
|
|
def test_check_grad(self):
|
|
self.check_grad(
|
|
['X'],
|
|
'Out',
|
|
check_prim=True,
|
|
check_pir=True,
|
|
check_prim_pir=True,
|
|
)
|
|
|
|
|
|
class TestTileOpRank_ZeroDim1(TestTileOpRank1):
|
|
def init_data(self):
|
|
self.ori_shape = []
|
|
self.repeat_times = []
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = False
|
|
self.enable_cinn = False
|
|
|
|
|
|
class TestTileOpRank_ZeroDim2(TestTileOpRank1):
|
|
def init_data(self):
|
|
self.ori_shape = []
|
|
self.repeat_times = [2]
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = False
|
|
self.enable_cinn = False
|
|
|
|
|
|
class TestTileOpRank_ZeroDim3(TestTileOpRank1):
|
|
def init_data(self):
|
|
self.ori_shape = []
|
|
self.repeat_times = [2, 3]
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = False
|
|
self.enable_cinn = False
|
|
|
|
|
|
class TestTileOpRank_ZeroSize(TestTileOpRank1):
|
|
def setUp(self):
|
|
self.op_type = "tile"
|
|
self.python_api = paddle.tile
|
|
self.public_python_api = paddle.tile
|
|
self.init_data()
|
|
|
|
self.inputs = {'X': np.random.random(self.ori_shape).astype("float64")}
|
|
self.attrs = {'repeat_times': self.repeat_times}
|
|
output = np.tile(self.inputs['X'], self.repeat_times)
|
|
self.outputs = {'Out': output}
|
|
|
|
def init_data(self):
|
|
self.ori_shape = [2, 0]
|
|
self.repeat_times = [1]
|
|
|
|
def test_check_output(self):
|
|
self.check_output(check_pir=True)
|
|
|
|
def test_check_grad(self):
|
|
self.check_grad(
|
|
['X'],
|
|
'Out',
|
|
user_defined_grads=[np.zeros(self.ori_shape)],
|
|
check_pir=True,
|
|
)
|
|
|
|
|
|
class TestTileOpRank_ZeroSize2(TestTileOpRank_ZeroSize):
|
|
def init_data(self):
|
|
self.ori_shape = [2, 100]
|
|
self.repeat_times = [0]
|
|
|
|
|
|
# with dimension expanding
|
|
class TestTileOpRank2Expanding(TestTileOpRank1):
|
|
def init_data(self):
|
|
self.ori_shape = [120]
|
|
self.repeat_times = [2, 2]
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = True
|
|
|
|
|
|
class TestTileOpRank2(TestTileOpRank1):
|
|
def init_data(self):
|
|
self.ori_shape = [12, 14]
|
|
self.repeat_times = [2, 3]
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = True
|
|
|
|
|
|
class TestTileOpRank3_Corner(TestTileOpRank1):
|
|
def init_data(self):
|
|
self.ori_shape = (2, 10, 5)
|
|
self.repeat_times = (1, 1, 1)
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = True
|
|
|
|
|
|
class TestTileOpRank3_Corner2(TestTileOpRank1):
|
|
def init_data(self):
|
|
self.ori_shape = (2, 10, 5)
|
|
self.repeat_times = (2, 2)
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = True
|
|
|
|
|
|
class TestTileOpRank3(TestTileOpRank1):
|
|
def init_data(self):
|
|
self.ori_shape = (2, 4, 15)
|
|
self.repeat_times = (2, 1, 4)
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = True
|
|
|
|
|
|
class TestTileOpRank4(TestTileOpRank1):
|
|
def init_data(self):
|
|
self.ori_shape = (2, 4, 5, 7)
|
|
self.repeat_times = (3, 2, 1, 2)
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = True
|
|
|
|
def test_check_output(self):
|
|
# todo: enable check_prim_pir
|
|
self.check_output(check_cinn=self.check_cinn, check_pir=True)
|
|
|
|
def test_check_grad(self):
|
|
self.check_grad(
|
|
['X'],
|
|
'Out',
|
|
check_prim=True,
|
|
check_pir=True,
|
|
)
|
|
|
|
|
|
class TestTileOpRank5(TestTileOpRank1):
|
|
def init_data(self):
|
|
self.ori_shape = (4, 2, 2, 2, 6)
|
|
self.repeat_times = (2, 3, 4, 5, 7)
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = True
|
|
|
|
|
|
class TestTileOpRank6(TestTileOpRank1):
|
|
def init_data(self):
|
|
self.ori_shape = (2, 2, 2, 2, 2, 6)
|
|
self.repeat_times = (2, 2, 3, 4, 5, 7)
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = True
|
|
|
|
|
|
# Situation 2: repeat_times is a list (with tensor)
|
|
# CINN not support repeat_times is a tensor now
|
|
class TestTileOpRank1_tensor_attr(OpTest):
|
|
def setUp(self):
|
|
self.op_type = "tile"
|
|
self.python_api = paddle.tile
|
|
self.init_data()
|
|
repeat_times_tensor = []
|
|
for index, ele in enumerate(self.repeat_times):
|
|
repeat_times_tensor.append(
|
|
("x" + str(index), np.ones(1).astype('int32') * ele)
|
|
)
|
|
|
|
self.inputs = {
|
|
'X': np.random.random(self.ori_shape).astype("float64"),
|
|
'repeat_times_tensor': repeat_times_tensor,
|
|
}
|
|
self.attrs = {"repeat_times": self.infer_repeat_times}
|
|
output = np.tile(self.inputs['X'], self.repeat_times)
|
|
self.outputs = {'Out': output}
|
|
|
|
def init_data(self):
|
|
self.ori_shape = [100]
|
|
self.repeat_times = [2]
|
|
self.infer_repeat_times = [-1]
|
|
|
|
def test_check_output(self):
|
|
self.check_output(check_pir=True, check_symbol_infer=False)
|
|
|
|
def test_check_grad(self):
|
|
self.check_grad(['X'], 'Out')
|
|
|
|
|
|
class TestTileOpRank2_Corner_tensor_attr(TestTileOpRank1_tensor_attr):
|
|
def init_data(self):
|
|
self.ori_shape = [12, 14]
|
|
self.repeat_times = [1, 1]
|
|
self.infer_repeat_times = [1, -1]
|
|
|
|
|
|
class TestTileOpRank2_attr_tensor(TestTileOpRank1_tensor_attr):
|
|
def init_data(self):
|
|
self.ori_shape = [12, 14]
|
|
self.repeat_times = [2, 3]
|
|
self.infer_repeat_times = [-1, 3]
|
|
|
|
|
|
# Situation 3: repeat_times is a tensor
|
|
# CINN not support repeat_times is a tensor now
|
|
class TestTileOpRank1_tensor(OpTest):
|
|
def setUp(self):
|
|
self.op_type = "tile"
|
|
self.python_api = paddle.tile
|
|
self.init_data()
|
|
|
|
self.inputs = {
|
|
'X': np.random.random(self.ori_shape).astype("float64"),
|
|
'RepeatTimes': np.array(self.repeat_times).astype("int32"),
|
|
}
|
|
self.attrs = {}
|
|
output = np.tile(self.inputs['X'], self.repeat_times)
|
|
self.outputs = {'Out': output}
|
|
|
|
def init_data(self):
|
|
self.ori_shape = [100]
|
|
self.repeat_times = [2]
|
|
|
|
def test_check_output(self):
|
|
self.check_output(check_pir=True, check_symbol_infer=False)
|
|
|
|
def test_check_grad(self):
|
|
self.check_grad(['X'], 'Out')
|
|
|
|
|
|
class TestTileOpRank2_tensor(TestTileOpRank1_tensor):
|
|
def init_data(self):
|
|
self.ori_shape = [12, 14]
|
|
self.repeat_times = [2, 3]
|
|
|
|
|
|
# Situation 4: input x is Integer
|
|
class TestTileOpInteger(OpTest):
|
|
def setUp(self):
|
|
self.op_type = "tile"
|
|
self.python_api = paddle.tile
|
|
self.inputs = {
|
|
'X': np.random.randint(10, size=(4, 4, 5)).astype("int32")
|
|
}
|
|
self.attrs = {'repeat_times': [2, 1, 4]}
|
|
output = np.tile(self.inputs['X'], (2, 1, 4))
|
|
self.outputs = {'Out': output}
|
|
self.if_enable_cinn()
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = True
|
|
|
|
def test_check_output(self):
|
|
self.check_output(check_cinn=self.check_cinn, check_pir=True)
|
|
|
|
|
|
class TestTileFP16OP(OpTest):
|
|
def setUp(self):
|
|
self.op_type = "tile"
|
|
self.dtype = np.float16
|
|
self.python_api = paddle.tile
|
|
self.prim_op_type = "prim"
|
|
self.public_python_api = paddle.tile
|
|
self.init_data()
|
|
x = np.random.uniform(10, size=self.ori_shape).astype(self.dtype)
|
|
output = np.tile(x, self.repeat_times)
|
|
self.inputs = {'X': x}
|
|
self.attrs = {'repeat_times': self.repeat_times}
|
|
self.outputs = {'Out': output}
|
|
self.if_enable_cinn()
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = True
|
|
|
|
def init_data(self):
|
|
self.dtype = np.float16
|
|
self.ori_shape = [100, 4, 5]
|
|
self.repeat_times = [2, 1, 4]
|
|
|
|
def test_check_output(self):
|
|
self.check_output(
|
|
check_cinn=self.check_cinn, check_pir=True, check_prim_pir=True
|
|
)
|
|
|
|
def test_check_grad(self):
|
|
self.check_grad(
|
|
['X'],
|
|
'Out',
|
|
check_prim=True,
|
|
check_pir=True,
|
|
check_prim_pir=True,
|
|
)
|
|
|
|
|
|
@unittest.skipIf(
|
|
not (core.is_compiled_with_cuda() or is_custom_device())
|
|
or not core.is_bfloat16_supported(get_device_place()),
|
|
"core is not compiled with CUDA and not support the bfloat16",
|
|
)
|
|
class TestTileBF16OP(OpTest):
|
|
def setUp(self):
|
|
self.op_type = 'tile'
|
|
self.__class__.op_type = self.op_type
|
|
self.python_api = paddle.tile
|
|
self.prim_op_type = "prim"
|
|
self.public_python_api = paddle.tile
|
|
self.init_data()
|
|
x = np.random.uniform(10, size=self.ori_shape).astype(np.float32)
|
|
output = np.tile(x, self.repeat_times)
|
|
self.inputs = {'X': convert_float_to_uint16(x)}
|
|
self.attrs = {'repeat_times': self.repeat_times}
|
|
self.outputs = {'Out': convert_float_to_uint16(output)}
|
|
self.if_enable_cinn()
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = True
|
|
|
|
def test_check_output(self):
|
|
place = get_device_place()
|
|
self.check_output_with_place(
|
|
place,
|
|
check_cinn=self.check_cinn,
|
|
check_pir=True,
|
|
check_prim_pir=True,
|
|
)
|
|
|
|
def init_data(self):
|
|
self.dtype = np.uint16
|
|
self.ori_shape = [100, 4, 5]
|
|
self.repeat_times = [2, 1, 4]
|
|
|
|
def test_check_grad(self):
|
|
place = get_device_place()
|
|
self.check_grad_with_place(
|
|
place,
|
|
['X'],
|
|
'Out',
|
|
check_prim=True,
|
|
check_pir=True,
|
|
check_prim_pir=True,
|
|
)
|
|
|
|
|
|
# Situation 5: input x is Bool
|
|
class TestTileOpBoolean(OpTest):
|
|
def setUp(self):
|
|
self.op_type = "tile"
|
|
self.python_api = paddle.tile
|
|
self.inputs = {'X': np.random.randint(2, size=(2, 4, 5)).astype("bool")}
|
|
self.attrs = {'repeat_times': [2, 1, 4]}
|
|
output = np.tile(self.inputs['X'], (2, 1, 4))
|
|
self.outputs = {'Out': output}
|
|
self.if_enable_cinn()
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = True
|
|
|
|
def test_check_output(self):
|
|
self.check_output(check_cinn=self.check_cinn, check_pir=True)
|
|
|
|
|
|
# Situation 56: input x is Integer
|
|
class TestTileOpInt64_t(OpTest):
|
|
def setUp(self):
|
|
self.op_type = "tile"
|
|
self.python_api = paddle.tile
|
|
self.inputs = {
|
|
'X': np.random.randint(10, size=(2, 4, 5)).astype("int64")
|
|
}
|
|
self.attrs = {'repeat_times': [2, 1, 4]}
|
|
output = np.tile(self.inputs['X'], (2, 1, 4))
|
|
self.outputs = {'Out': output}
|
|
self.if_enable_cinn()
|
|
|
|
def if_enable_cinn(self):
|
|
self.check_cinn = True
|
|
|
|
def test_check_output(self):
|
|
self.check_output(check_cinn=self.check_cinn, check_pir=True)
|
|
|
|
|
|
class TestTileError(unittest.TestCase):
|
|
def test_errors(self):
|
|
with paddle.static.program_guard(
|
|
paddle.static.Program(), paddle.static.Program()
|
|
):
|
|
x1 = base.create_lod_tensor(
|
|
np.array([[-1]]), [[1]], base.CPUPlace()
|
|
)
|
|
repeat_times = [2, 2]
|
|
self.assertRaises(TypeError, paddle.tile, x1, repeat_times)
|
|
x2 = paddle.static.data(name='x2', shape=[-1, 4], dtype="uint8")
|
|
self.assertRaises(TypeError, paddle.tile, x2, repeat_times)
|
|
x3 = paddle.static.data(name='x3', shape=[-1, 4], dtype="bool")
|
|
x3.stop_gradient = False
|
|
self.assertRaises(ValueError, paddle.tile, x3, repeat_times)
|
|
|
|
|
|
class TestTileAPIStatic(unittest.TestCase):
|
|
def test_api(self):
|
|
with paddle.static.program_guard(
|
|
paddle.static.Program(), paddle.static.Program()
|
|
):
|
|
repeat_times = [2, 2]
|
|
x1 = paddle.static.data(name='x1', shape=[-1, 4], dtype="int32")
|
|
out = paddle.tile(x1, repeat_times)
|
|
|
|
# Test repeat_times contains Tensor
|
|
positive_2 = paddle.tensor.fill_constant([], dtype="int32", value=2)
|
|
out2 = paddle.tile(x1, repeat_times=[positive_2, 2])
|
|
|
|
# Test repeat_times contains 1D Tensor
|
|
positive_2_1d = paddle.tensor.fill_constant(
|
|
[1], dtype="int32", value=2
|
|
)
|
|
out3 = paddle.tile(x1, repeat_times=[positive_2_1d, 2])
|
|
|
|
|
|
# Test python API
|
|
class TestTileAPI(unittest.TestCase):
|
|
def test_api(self):
|
|
with base.dygraph.guard():
|
|
np_x = np.random.random([12, 14]).astype("float32")
|
|
x = paddle.to_tensor(np_x)
|
|
|
|
positive_2 = np.array([2]).astype("int32")
|
|
positive_2 = paddle.to_tensor(positive_2)
|
|
|
|
repeat_times = np.array([2, 3]).astype("int32")
|
|
repeat_times = paddle.to_tensor(repeat_times)
|
|
|
|
out_1 = paddle.tile(x, repeat_times=[2, 3])
|
|
out_2 = paddle.tile(x, repeat_times=[positive_2, 3])
|
|
out_3 = paddle.tile(x, repeat_times=repeat_times)
|
|
|
|
np.testing.assert_array_equal(out_1.numpy(), np.tile(np_x, (2, 3)))
|
|
np.testing.assert_array_equal(out_2.numpy(), np.tile(np_x, (2, 3)))
|
|
np.testing.assert_array_equal(out_3.numpy(), np.tile(np_x, (2, 3)))
|
|
|
|
|
|
class TestTileAPI7D(unittest.TestCase):
|
|
def init_data(self):
|
|
self.ori_shape = [1, 2, 3, 4, 5]
|
|
self.repeat_times = [1, 1, 1, 2, 1, 2, 1]
|
|
|
|
def _test_api(self, place):
|
|
with base.dygraph.guard():
|
|
np_x = np.random.random(self.ori_shape).astype("float32")
|
|
x = paddle.to_tensor(np_x, place=place)
|
|
x.stop_gradient = False
|
|
repeat_times = self.repeat_times
|
|
out = paddle.tile(x, repeat_times)
|
|
np.testing.assert_array_equal(
|
|
out.numpy(), np.tile(np_x, repeat_times)
|
|
)
|
|
loss = out.sum()
|
|
loss.backward()
|
|
np.testing.assert_array_equal(x.grad.shape, x.shape)
|
|
|
|
def test_tile7d(self):
|
|
places = get_places()
|
|
for place in places:
|
|
self.init_data()
|
|
self._test_api(place)
|
|
|
|
|
|
class TestTileAPI7Dcase2(TestTileAPI7D):
|
|
def init_data(self):
|
|
self.ori_shape = [1, 2, 3, 4, 5, 1, 2]
|
|
self.repeat_times = [3, 2, 2, 1, 1, 2, 1]
|
|
|
|
|
|
class TestTileDoubleGradCheck(unittest.TestCase):
|
|
def tile_wrapper(self, x):
|
|
return paddle.tile(x[0], [2, 1])
|
|
|
|
@prog_scope()
|
|
def func(self, place):
|
|
# the shape of input variable should be clearly specified, not include -1.
|
|
eps = 0.005
|
|
dtype = np.float32
|
|
|
|
data = paddle.static.data('data', [1, 2], dtype)
|
|
data.persistable = True
|
|
out = paddle.tile(data, [2, 1])
|
|
data_arr = np.random.uniform(-1, 1, data.shape).astype(dtype)
|
|
|
|
gradient_checker.double_grad_check(
|
|
[data], out, x_init=[data_arr], place=place, eps=eps
|
|
)
|
|
gradient_checker.double_grad_check_for_dygraph(
|
|
self.tile_wrapper, [data], out, x_init=[data_arr], place=place
|
|
)
|
|
|
|
def test_grad(self):
|
|
paddle.enable_static()
|
|
for p in get_places():
|
|
self.func(p)
|
|
|
|
|
|
class TestTileTripleGradCheck(unittest.TestCase):
|
|
def tile_wrapper(self, x):
|
|
return paddle.tile(x[0], [2, 1])
|
|
|
|
@prog_scope()
|
|
def func(self, place):
|
|
# the shape of input variable should be clearly specified, not include -1.
|
|
eps = 0.005
|
|
dtype = np.float32
|
|
|
|
data = paddle.static.data('data', [1, 2], dtype)
|
|
data.persistable = True
|
|
out = paddle.tile(data, [2, 1])
|
|
data_arr = np.random.uniform(-1, 1, data.shape).astype(dtype)
|
|
|
|
gradient_checker.triple_grad_check(
|
|
[data], out, x_init=[data_arr], place=place, eps=eps
|
|
)
|
|
gradient_checker.triple_grad_check_for_dygraph(
|
|
self.tile_wrapper, [data], out, x_init=[data_arr], place=place
|
|
)
|
|
|
|
def test_grad(self):
|
|
paddle.enable_static()
|
|
for p in get_places():
|
|
self.func(p)
|
|
|
|
|
|
class TestTileAPI_ZeroDim(unittest.TestCase):
|
|
def test_dygraph(self):
|
|
paddle.disable_static()
|
|
|
|
x = paddle.rand([])
|
|
x.stop_gradient = False
|
|
|
|
out = paddle.tile(x, [])
|
|
out.retain_grads()
|
|
out.backward()
|
|
self.assertEqual(out.shape, [])
|
|
self.assertEqual(x.grad.shape, [])
|
|
self.assertEqual(out.grad.shape, [])
|
|
|
|
out = paddle.tile(x, [3])
|
|
out.retain_grads()
|
|
out.backward()
|
|
self.assertEqual(out.shape, [3])
|
|
self.assertEqual(x.grad.shape, [])
|
|
self.assertEqual(out.grad.shape, [3])
|
|
|
|
out = paddle.tile(x, [2, 3])
|
|
out.retain_grads()
|
|
out.backward()
|
|
self.assertEqual(out.shape, [2, 3])
|
|
self.assertEqual(x.grad.shape, [])
|
|
self.assertEqual(out.grad.shape, [2, 3])
|
|
|
|
paddle.enable_static()
|
|
|
|
|
|
class Testfp16TileOp(unittest.TestCase):
|
|
def testfp16(self):
|
|
if not (paddle.is_compiled_with_cuda() or is_custom_device()):
|
|
return
|
|
input_x = (np.random.random([1, 2, 3])).astype('float16')
|
|
with paddle.static.program_guard(paddle.static.Program()):
|
|
x = paddle.static.data(name="x", shape=[1, 2, 3], dtype='float16')
|
|
repeat_times = [2, 2]
|
|
out = paddle.tile(x, repeat_times=repeat_times)
|
|
place = get_device_place()
|
|
exe = paddle.static.Executor(place)
|
|
exe.run(paddle.static.default_startup_program())
|
|
out = exe.run(feed={'x': input_x}, fetch_list=[out])
|
|
|
|
|
|
# Test alias for 'input' and 'dims'
|
|
class TestTileAlias(unittest.TestCase):
|
|
def test_alias(self):
|
|
with base.dygraph.guard():
|
|
x_np = np.random.random((2, 3)).astype("float32")
|
|
x = paddle.to_tensor(x_np)
|
|
repeat_times = [2, 3]
|
|
|
|
# 1. Standard call (Benchmark)
|
|
out_ref = paddle.tile(x, repeat_times=repeat_times)
|
|
|
|
# 2. Test alias: input -> x
|
|
out_input = paddle.tile(input=x, repeat_times=repeat_times)
|
|
np.testing.assert_array_equal(out_ref.numpy(), out_input.numpy())
|
|
|
|
# 3. Test alias: dims -> repeat_times
|
|
out_dims = paddle.tile(x=x, dims=repeat_times)
|
|
np.testing.assert_array_equal(out_ref.numpy(), out_dims.numpy())
|
|
|
|
# 4. Test both aliases: input -> x, dims -> repeat_times
|
|
out_both = paddle.tile(input=x, dims=repeat_times)
|
|
np.testing.assert_array_equal(out_ref.numpy(), out_both.numpy())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
paddle.enable_static()
|
|
unittest.main()
|