From fd1ecfc50a99886d47263700b8d3ff439f3bb34d Mon Sep 17 00:00:00 2001 From: zyfncg Date: Sun, 3 Apr 2022 11:50:17 +0800 Subject: [PATCH] Add randperm and range yaml (#41265) * add randperm and range yaml * add eager test for randperm --- paddle/fluid/operators/range_op.cc | 2 +- paddle/phi/infermeta/nullary.cc | 5 + paddle/phi/infermeta/nullary.h | 2 + paddle/phi/infermeta/ternary.cc | 100 +++++++++--------- paddle/phi/infermeta/ternary.h | 10 +- .../{range_kernel.h => arange_kernel.h} | 10 +- .../cpu/{range_kernel.cc => arange_kernel.cc} | 14 +-- .../gpu/{range_kernel.cu => arange_kernel.cu} | 14 +-- paddle/phi/ops/compat/range_sig.cc | 17 +++ python/paddle/fluid/layers/tensor.py | 8 +- .../fluid/tests/unittests/test_randperm_op.py | 19 ++++ .../fluid/tests/unittests/test_range.py | 13 ++- python/paddle/tensor/random.py | 7 +- python/paddle/utils/code_gen/api.yaml | 26 +++++ 14 files changed, 167 insertions(+), 80 deletions(-) rename paddle/phi/kernels/{range_kernel.h => arange_kernel.h} (78%) rename paddle/phi/kernels/cpu/{range_kernel.cc => arange_kernel.cc} (78%) rename paddle/phi/kernels/gpu/{range_kernel.cu => arange_kernel.cu} (86%) create mode 100644 paddle/phi/ops/compat/range_sig.cc diff --git a/paddle/fluid/operators/range_op.cc b/paddle/fluid/operators/range_op.cc index ddfbdbace0..80fdb2ce6c 100644 --- a/paddle/fluid/operators/range_op.cc +++ b/paddle/fluid/operators/range_op.cc @@ -61,6 +61,6 @@ class RangeOpMaker : public framework::OpProtoAndCheckerMaker { namespace ops = paddle::operators; DECLARE_INFER_SHAPE_FUNCTOR(range, RangeInferMetaFunctor, - PD_INFER_META(phi::RangeInferMeta)); + PD_INFER_META(phi::ArangeInferMeta)); REGISTER_OP_WITHOUT_GRADIENT(range, ops::RangeOp, ops::RangeOpMaker, RangeInferMetaFunctor); diff --git a/paddle/phi/infermeta/nullary.cc b/paddle/phi/infermeta/nullary.cc index 4a11d24a98..6a05e1b4d7 100644 --- a/paddle/phi/infermeta/nullary.cc +++ b/paddle/phi/infermeta/nullary.cc @@ -58,6 +58,11 @@ void GaussianRandomInferMeta(const IntArray& shape, out->set_layout(DataLayout::NCHW); } +void RandpermInferMeta(int n, DataType dtype, MetaTensor* out) { + out->set_dims(phi::make_ddim({n})); + out->set_dtype(dtype); +} + void TruncatedGaussianRandomInferMeta(const std::vector& shape, float mean, float std, diff --git a/paddle/phi/infermeta/nullary.h b/paddle/phi/infermeta/nullary.h index 4c9eb0b62a..ada44658a2 100644 --- a/paddle/phi/infermeta/nullary.h +++ b/paddle/phi/infermeta/nullary.h @@ -53,6 +53,8 @@ void GaussianRandomInferMeta(const IntArray& shape, DataType dtype, MetaTensor* out); +void RandpermInferMeta(int n, DataType dtype, MetaTensor* out); + void TruncatedGaussianRandomInferMeta(const std::vector& shape, float mean, float std, diff --git a/paddle/phi/infermeta/ternary.cc b/paddle/phi/infermeta/ternary.cc index 582dcb0137..3e4aa7b444 100644 --- a/paddle/phi/infermeta/ternary.cc +++ b/paddle/phi/infermeta/ternary.cc @@ -141,6 +141,56 @@ void AddmmInferMeta(const MetaTensor& input, out->set_dtype(input.dtype()); } +void ArangeInferMeta(const MetaTensor& start, + const MetaTensor& end, + const MetaTensor& step, + MetaTensor* out) { + auto start_dims = start.dims(); + auto end_dims = end.dims(); + auto step_dims = step.dims(); + PADDLE_ENFORCE_EQ( + start_dims.size(), + 1, + phi::errors::InvalidArgument( + "The dim of the shape of Input(Start) should be 1, but got %d", + start_dims.size())); + + PADDLE_ENFORCE_EQ(start_dims[0], + 1, + phi::errors::InvalidArgument( + "The first dim of the shape of Input(Start) should " + "be 1, but got %d", + start_dims[0])); + PADDLE_ENFORCE_EQ( + end_dims.size(), + 1, + phi::errors::InvalidArgument( + "The dim of the shape of Input(End) should be 1, but got %d", + end_dims.size())); + + PADDLE_ENFORCE_EQ( + end_dims[0], + 1, + phi::errors::InvalidArgument("The first dim of the shape of " + "Input(End) should be 1, but got %d", + end_dims[0])); + PADDLE_ENFORCE_EQ( + step_dims.size(), + 1, + phi::errors::InvalidArgument( + "The dim of the shape of Input(Step) should be 1, but got %d", + step_dims.size())); + + PADDLE_ENFORCE_EQ(step_dims[0], + 1, + phi::errors::InvalidArgument( + "The first dim of the shape of Input(Step) should " + "be 1, but got %d", + step_dims[0])); + out->set_dims({-1}); + out->set_dtype(start.dtype()); +} + void GraphSendRecvInferMeta(const MetaTensor& x, const MetaTensor& src_index, const MetaTensor& dst_index, @@ -345,56 +395,6 @@ void PutAlongAxisInferMeta(const MetaTensor& x, out->set_dtype(x.dtype()); } -void RangeInferMeta(const MetaTensor& start, - const MetaTensor& end, - const MetaTensor& step, - MetaTensor* out) { - auto start_dims = start.dims(); - auto end_dims = end.dims(); - auto step_dims = step.dims(); - PADDLE_ENFORCE_EQ( - start_dims.size(), - 1, - phi::errors::InvalidArgument( - "The dim of the shape of Input(Start) should be 1, but got %d", - start_dims.size())); - - PADDLE_ENFORCE_EQ(start_dims[0], - 1, - phi::errors::InvalidArgument( - "The first dim of the shape of Input(Start) should " - "be 1, but got %d", - start_dims[0])); - PADDLE_ENFORCE_EQ( - end_dims.size(), - 1, - phi::errors::InvalidArgument( - "The dim of the shape of Input(End) should be 1, but got %d", - end_dims.size())); - - PADDLE_ENFORCE_EQ( - end_dims[0], - 1, - phi::errors::InvalidArgument("The first dim of the shape of " - "Input(End) should be 1, but got %d", - end_dims[0])); - PADDLE_ENFORCE_EQ( - step_dims.size(), - 1, - phi::errors::InvalidArgument( - "The dim of the shape of Input(Step) should be 1, but got %d", - step_dims.size())); - - PADDLE_ENFORCE_EQ(step_dims[0], - 1, - phi::errors::InvalidArgument( - "The first dim of the shape of Input(Step) should " - "be 1, but got %d", - step_dims[0])); - out->set_dims({-1}); - out->set_dtype(start.dtype()); -} - void RoiAlignInferMeta(const MetaTensor& x, const MetaTensor& boxes, paddle::optional boxes_num, diff --git a/paddle/phi/infermeta/ternary.h b/paddle/phi/infermeta/ternary.h index c18dde42f1..00e4981168 100644 --- a/paddle/phi/infermeta/ternary.h +++ b/paddle/phi/infermeta/ternary.h @@ -47,6 +47,11 @@ void AddmmInferMeta(const MetaTensor& input, float beta, MetaTensor* out); +void ArangeInferMeta(const MetaTensor& start, + const MetaTensor& end, + const MetaTensor& step, + MetaTensor* out); + void GraphSendRecvInferMeta(const MetaTensor& x, const MetaTensor& src_index, const MetaTensor& dst_index, @@ -81,11 +86,6 @@ void PutAlongAxisInferMeta(const MetaTensor& x, const std::string& reduce, MetaTensor* out); -void RangeInferMeta(const MetaTensor& start, - const MetaTensor& end, - const MetaTensor& step, - MetaTensor* out); - void RoiAlignInferMeta(const MetaTensor& x, const MetaTensor& boxes, paddle::optional boxes_num, diff --git a/paddle/phi/kernels/range_kernel.h b/paddle/phi/kernels/arange_kernel.h similarity index 78% rename from paddle/phi/kernels/range_kernel.h rename to paddle/phi/kernels/arange_kernel.h index c76308193a..be60824ac2 100644 --- a/paddle/phi/kernels/range_kernel.h +++ b/paddle/phi/kernels/arange_kernel.h @@ -19,10 +19,10 @@ namespace phi { template -void RangeKernel(const Context& dev_ctx, - const DenseTensor& start, - const DenseTensor& end, - const DenseTensor& step, - DenseTensor* out); +void ArangeKernel(const Context& dev_ctx, + const DenseTensor& start, + const DenseTensor& end, + const DenseTensor& step, + DenseTensor* out); } // namespace phi diff --git a/paddle/phi/kernels/cpu/range_kernel.cc b/paddle/phi/kernels/cpu/arange_kernel.cc similarity index 78% rename from paddle/phi/kernels/cpu/range_kernel.cc rename to paddle/phi/kernels/cpu/arange_kernel.cc index 8731696f61..478251b0d3 100644 --- a/paddle/phi/kernels/cpu/range_kernel.cc +++ b/paddle/phi/kernels/cpu/arange_kernel.cc @@ -12,7 +12,7 @@ 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 "paddle/phi/kernels/range_kernel.h" +#include "paddle/phi/kernels/arange_kernel.h" #include "paddle/phi/backends/cpu/cpu_context.h" #include "paddle/phi/core/kernel_registry.h" #include "paddle/phi/kernels/funcs/range_function.h" @@ -20,11 +20,11 @@ limitations under the License. */ namespace phi { template -void RangeKernel(const Context& dev_ctx, - const DenseTensor& start, - const DenseTensor& end, - const DenseTensor& step, - DenseTensor* out) { +void ArangeKernel(const Context& dev_ctx, + const DenseTensor& start, + const DenseTensor& end, + const DenseTensor& step, + DenseTensor* out) { T start_value = start.data()[0]; T end_value = end.data()[0]; T step_value = step.data()[0]; @@ -42,4 +42,4 @@ void RangeKernel(const Context& dev_ctx, } // namespace phi PD_REGISTER_KERNEL( - range, CPU, ALL_LAYOUT, phi::RangeKernel, float, double, int, int64_t) {} + arange, CPU, ALL_LAYOUT, phi::ArangeKernel, float, double, int, int64_t) {} diff --git a/paddle/phi/kernels/gpu/range_kernel.cu b/paddle/phi/kernels/gpu/arange_kernel.cu similarity index 86% rename from paddle/phi/kernels/gpu/range_kernel.cu rename to paddle/phi/kernels/gpu/arange_kernel.cu index d9a98f06d0..916f6aa553 100644 --- a/paddle/phi/kernels/gpu/range_kernel.cu +++ b/paddle/phi/kernels/gpu/arange_kernel.cu @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "paddle/phi/kernels/range_kernel.h" +#include "paddle/phi/kernels/arange_kernel.h" #include "paddle/phi/backends/gpu/gpu_context.h" #include "paddle/phi/core/kernel_registry.h" @@ -40,11 +40,11 @@ __global__ void Range(T start, T step, int64_t size, T* out) { } template -void RangeKernel(const Context& dev_ctx, - const DenseTensor& start, - const DenseTensor& end, - const DenseTensor& step, - DenseTensor* out) { +void ArangeKernel(const Context& dev_ctx, + const DenseTensor& start, + const DenseTensor& end, + const DenseTensor& step, + DenseTensor* out) { T start_value = GetValue(dev_ctx, start); T end_value = GetValue(dev_ctx, end); T step_value = GetValue(dev_ctx, step); @@ -63,7 +63,7 @@ void RangeKernel(const Context& dev_ctx, } // namespace phi PD_REGISTER_KERNEL( - range, GPU, ALL_LAYOUT, phi::RangeKernel, float, double, int64_t, int) { + arange, GPU, ALL_LAYOUT, phi::ArangeKernel, float, double, int64_t, int) { kernel->InputAt(0).SetBackend(phi::Backend::CPU); kernel->InputAt(1).SetBackend(phi::Backend::CPU); kernel->InputAt(2).SetBackend(phi::Backend::CPU); diff --git a/paddle/phi/ops/compat/range_sig.cc b/paddle/phi/ops/compat/range_sig.cc new file mode 100644 index 0000000000..d48898bd84 --- /dev/null +++ b/paddle/phi/ops/compat/range_sig.cc @@ -0,0 +1,17 @@ +/* Copyright (c) 2022 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. */ + +#include "paddle/phi/core/compat/op_utils.h" + +PD_REGISTER_BASE_KERNEL_NAME(range, arange); diff --git a/python/paddle/fluid/layers/tensor.py b/python/paddle/fluid/layers/tensor.py index ff7008fddd..81a60bf517 100644 --- a/python/paddle/fluid/layers/tensor.py +++ b/python/paddle/fluid/layers/tensor.py @@ -21,7 +21,7 @@ import warnings from ..layer_helper import LayerHelper from ..param_attr import ParamAttr from ..initializer import Initializer -from ..framework import convert_np_dtype_to_dtype_, _non_static_mode, _varbase_creator, device_guard, _in_legacy_dygraph, in_dygraph_mode +from ..framework import _current_expected_place, convert_np_dtype_to_dtype_, _non_static_mode, _varbase_creator, device_guard, _in_legacy_dygraph, in_dygraph_mode from ..framework import Variable from ..initializer import Constant from ..core import VarDesc @@ -1433,6 +1433,10 @@ def range(start, end, step, dtype, name=None): if not isinstance(dtype, core.VarDesc.VarType): dtype = convert_np_dtype_to_dtype_(dtype) + if in_dygraph_mode(): + return _C_ops.final_state_arange(start, end, step, dtype, + _current_expected_place()) + if not isinstance(start, Variable): with device_guard("cpu"): start = fill_constant([1], dtype, start, force_cpu=True) @@ -1451,7 +1455,7 @@ def range(start, end, step, dtype, name=None): elif step.dtype != dtype: step = cast(step, dtype) - if _non_static_mode(): + if _in_legacy_dygraph(): out = _C_ops.range(start, end, step) out.stop_gradient = True return out diff --git a/python/paddle/fluid/tests/unittests/test_randperm_op.py b/python/paddle/fluid/tests/unittests/test_randperm_op.py index 2380ccb14a..5c9ab36fa3 100644 --- a/python/paddle/fluid/tests/unittests/test_randperm_op.py +++ b/python/paddle/fluid/tests/unittests/test_randperm_op.py @@ -18,6 +18,7 @@ from op_test import OpTest import paddle import paddle.fluid.core as core from paddle.static import program_guard, Program +from paddle.fluid.framework import _test_eager_guard import os @@ -50,6 +51,7 @@ class TestRandpermOp(OpTest): def setUp(self): self.op_type = "randperm" + self.python_api = paddle.randperm self.n = 200 self.dtype = "int64" @@ -72,6 +74,10 @@ class TestRandpermOp(OpTest): self.assertTrue( check_randperm_out(self.n, out_np), msg=error_msg(out_np)) + def test_eager(self): + with _test_eager_guard(): + self.test_check_output() + class TestRandpermOpN(TestRandpermOp): def init_attrs(self): @@ -130,6 +136,19 @@ class TestRandpermImperative(unittest.TestCase): paddle.enable_static() +class TestRandpermEager(unittest.TestCase): + def test_out(self): + paddle.disable_static() + n = 10 + with _test_eager_guard(): + for dtype in ['int32', np.int64, 'float32', 'float64']: + data_p = paddle.randperm(n, dtype) + data_np = data_p.numpy() + self.assertTrue( + check_randperm_out(n, data_np), msg=error_msg(data_np)) + paddle.enable_static() + + class TestRandomValue(unittest.TestCase): def test_fixed_random_number(self): # Test GPU Fixed random number, which is generated by 'curandStatePhilox4_32_10_t' diff --git a/python/paddle/fluid/tests/unittests/test_range.py b/python/paddle/fluid/tests/unittests/test_range.py index f129ae78cb..e19c1b227f 100644 --- a/python/paddle/fluid/tests/unittests/test_range.py +++ b/python/paddle/fluid/tests/unittests/test_range.py @@ -14,9 +14,15 @@ from __future__ import print_function +import paddle import unittest import numpy as np from op_test import OpTest +from functools import partial + + +def arange_wrapper(start, end, step, dtype=None): + return paddle.arange(start, end, step, dtype) class TestRangeOp(OpTest): @@ -36,33 +42,38 @@ class TestRangeOp(OpTest): def init_config(self): self.dtype = np.float32 + self.python_api = partial(arange_wrapper, dtype=self.dtype) self.case = (0, 1, 0.2) def test_check_output(self): - self.check_output() + self.check_output(check_eager=True) class TestFloatRangeOpCase0(TestRangeOp): def init_config(self): self.dtype = np.float32 + self.python_api = partial(arange_wrapper, dtype=self.dtype) self.case = (0, 5, 1) class TestInt32RangeOpCase0(TestRangeOp): def init_config(self): self.dtype = np.int32 + self.python_api = partial(arange_wrapper, dtype=self.dtype) self.case = (0, 5, 2) class TestInt32RangeOpCase1(TestRangeOp): def init_config(self): self.dtype = np.int32 + self.python_api = partial(arange_wrapper, dtype=self.dtype) self.case = (10, 1, -2) class TestInt32RangeOpCase2(TestRangeOp): def init_config(self): self.dtype = np.int32 + self.python_api = partial(arange_wrapper, dtype=self.dtype) self.case = (-1, -10, -2) diff --git a/python/paddle/tensor/random.py b/python/paddle/tensor/random.py index 1fa91ae148..20f4e73b27 100644 --- a/python/paddle/tensor/random.py +++ b/python/paddle/tensor/random.py @@ -22,7 +22,7 @@ from ..fluid.layers import utils import paddle from paddle import _C_ops from paddle.static import Variable -from paddle.fluid.framework import in_dygraph_mode, _in_legacy_dygraph +from ..fluid.framework import _in_legacy_dygraph, in_dygraph_mode __all__ = [] @@ -919,7 +919,10 @@ def randperm(n, dtype="int64", name=None): if not isinstance(dtype, core.VarDesc.VarType): dtype = convert_np_dtype_to_dtype_(dtype) - if paddle.in_dynamic_mode(): + if in_dygraph_mode(): + return _C_ops.final_state_randperm( + n, dtype, paddle.fluid.framework._current_expected_place()) + if _in_legacy_dygraph(): return _C_ops.randperm('n', n, 'seed', 0, 'dtype', dtype) if n < 1: diff --git a/python/paddle/utils/code_gen/api.yaml b/python/paddle/utils/code_gen/api.yaml index b3bf1f7890..0b855b0f96 100644 --- a/python/paddle/utils/code_gen/api.yaml +++ b/python/paddle/utils/code_gen/api.yaml @@ -97,6 +97,20 @@ kernel : func : any +- api : arange + args : (Tensor start, Tensor end, Tensor step, DataType dtype, Place place={}) + output : Tensor + infer_meta : + func : ArangeInferMeta + param : [start, end, step] + kernel : + func : arange + param : [start, end, step] + data_type : dtype + backend : place + data_transform : + support_trans_dtype : start, end, step + # arg_max - api : argmax args : (Tensor x, int64_t axis, bool keepdims, bool flatten, int dtype) @@ -1227,6 +1241,18 @@ data_type : x backward : put_along_axis_grad +- api : randperm + args : (int n, DataType dtype, Place place={}) + output : Tensor + infer_meta : + func : RandpermInferMeta + param : [n, dtype] + kernel : + func : randperm + param : [n, dtype] + data_type : dtype + backend : place + - api : reciprocal args : (Tensor x) output : Tensor -- GitLab