diff --git a/test/test_network_ops/test_repeat.py b/test/test_network_ops/test_repeat.py new file mode 100644 index 0000000000000000000000000000000000000000..61db71bf0d039db8d2f06a525ee21440ac201386 --- /dev/null +++ b/test/test_network_ops/test_repeat.py @@ -0,0 +1,61 @@ +# Copyright (c) 2020, Huawei Technologies.All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# 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 torch +import torch_npu +import numpy as np + +from torch_npu.testing.common_utils import TestCase, run_tests +from torch_npu.testing.common_device_type import instantiate_device_type_tests +from torch_npu.testing.util_test import create_common_tensor + +class TestRepeat(TestCase): + def cpu_op_exec(self, input1, size): + output = input1.repeat(size) + output = output.numpy() + return output + + def npu_op_exec(self, input1, size): + output = input1.repeat(size) + output = output.to("cpu") + output = output.numpy() + return output + + def test_repeat_common_shape_format(self, device): + shape_format = [ + [[np.float32, -1, (1280, 4)], [2,3]], + [[np.float32, 0, (1, 6, 4)], [2, 4, 8]], + [[np.float32, 0, (2, 4, 5)], [2, 6, 10]], + [[np.int32, 0, (2, 2, 1280, 4)], [2,2,3,5]], + [[np.int32, 0, (2, 1280, 4)], [3,2,6]], + [[np.int32, 0, (1, 6, 4)], [1, 2, 4, 8]], + [[np.int32, 0, (2, 4, 5)], [2, 5, 10]], + [[np.int64, 0, (2, 1280, 4)], [3,2,6]], + [[np.int64, 0, (1, 6, 4)], [1, 2, 4, 8]], + [[np.int64, 0, (2, 4, 5)], [2, 5, 10]], + [[np.float16, 0, (1280, 4)], [2, 3]], + [[np.float16, 0, (1024, 4)], [2, 3, 4]], + [[np.float16, 0, (1, 6, 4)], [2, 4, 8]], + [[np.float16, 0, (2, 4, 5)], [2, 6, 10]], + [[np.bool, 0, (1024, 4)], [2, 3, 4]] + ] + for item in shape_format: + cpu_input1, npu_input1 = create_common_tensor(item[0], 0, 100) + cpu_output = self.cpu_op_exec(cpu_input1, item[1]) + npu_output = self.npu_op_exec(npu_input1, item[1]) + self.assertRtolEqual(cpu_output, npu_output) + +instantiate_device_type_tests(TestRepeat, globals(), except_for='cpu') +if __name__ == "__main__": + run_tests() diff --git a/torch_npu/csrc/aten/ops/RepeatKernelNpu.cpp b/torch_npu/csrc/aten/ops/RepeatKernelNpu.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4ff2c3237e0ba9a19761744005c8b3e5eac61405 --- /dev/null +++ b/torch_npu/csrc/aten/ops/RepeatKernelNpu.cpp @@ -0,0 +1,60 @@ +// Copyright (c) 2020 Huawei Technologies Co., Ltd +// Copyright (c) 2019, Facebook CORPORATION. +// All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// 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. + +#include "torch_npu/csrc/framework/utils/OpAdapter.h" +#include "torch_npu/csrc/aten/NPUNativeFunctions.h" + +namespace at_npu { +namespace native { + +at::Tensor& repeat_out_npu_nocheck( + at::Tensor& result, + const at::Tensor& self, + at::IntArrayRef repeats) { + + OpCommand cmd; + cmd.Name("Tile") + .Input(self) + .Input(repeats) + .Output(result) + .Run(); + + return result; +} + +at::Tensor NPUNativeFunctions::repeat(const at::Tensor& self, at::IntArrayRef repeats) { + TORCH_CHECK(repeats.size() >= self.ndimension(), + "Number of dimensions of repeat dims can not be smaller than number of dimensions of tensor"); + at::Tensor selfCp = self; + if(repeats.size() > selfCp.ndimension()){ + auto diff = repeats.size() - selfCp.ndimension(); + for(int i=0;i