diff --git a/paddle/fluid/operators/empty_op.cc b/paddle/fluid/operators/empty_op.cc index 3d28ca90a5a15fd53a57034a4722a21842dc4b1c..717809715601728d66f83006a3bd7b0903d07108 100644 --- a/paddle/fluid/operators/empty_op.cc +++ b/paddle/fluid/operators/empty_op.cc @@ -109,6 +109,20 @@ class EmptyOp : public framework::OperatorWithKernel { framework::proto::VarType::Type(context.Attr("dtype")), context.GetPlace()); } + + framework::KernelSignature GetExpectedPtenKernelArgs( + const framework::ExecutionContext& ctx) const override { + std::string shape; + if (ctx.HasInput("ShapeTensor")) { + shape = "ShapeTensor"; + } else if (ctx.MultiInput("ShapeTensorList").size()) { + shape = "ShapeTensorList"; + } else { + shape = "shape"; + } + + return framework::KernelSignature("empty", {}, {shape}, {"Out"}); + } }; class EmptyOpVarTypeInference : public framework::VarTypeInference { diff --git a/paddle/pten/api/include/kernel_signature.h b/paddle/pten/api/include/kernel_signature.h index ebae064c336897c2aca58617b3d0dcc5d2292eb5..1c120edb9ab7bc188a7721f14fc16ccbf3b6d1f0 100644 --- a/paddle/pten/api/include/kernel_signature.h +++ b/paddle/pten/api/include/kernel_signature.h @@ -50,6 +50,11 @@ using dot_kernel = void (*)(const DeviceContext&, using flatten_kernel = void (*)(const DeviceContext&, const DenseTensor&, int, int, DenseTensor*); +using empty_kernel = void (*)(const DeviceContext&, + const ScalarArray&, + DenseTensor*); + +using empty_like_kernel = void (*)(const DeviceContext&, DenseTensor*); using full_kernel = void (*)(const DeviceContext&, const ScalarArray&, const Scalar&, diff --git a/paddle/pten/include/creation.h b/paddle/pten/include/creation.h index c5decb5fc5bd2b534c3f6d903c3f5ad9a9249b09..73c5999ca9247ac3d29c3cb852afd7bec8d3fe86 100644 --- a/paddle/pten/include/creation.h +++ b/paddle/pten/include/creation.h @@ -16,12 +16,60 @@ #include "paddle/pten/api/lib/utils/storage.h" #include "paddle/pten/include/infermeta.h" +#include "paddle/pten/kernels/empty_kernel.h" #include "paddle/pten/kernels/full_kernel.h" namespace pten { // TODO(YuanRisheng) This function name should be same as User API name. // TODO(zyfncg) Automatic code generation +template +DenseTensor Empty(const ContextT& dev_ctx, + const ScalarArray& shape, + DataType dtype = DataType::FLOAT32, + Backend backend = Backend::CPU, // Is backend needed here? + DataLayout layout = DataLayout::NCHW) { + auto out_meta = CreateInferMeta(shape, dtype, layout); + pten::DenseTensor dense_out( + pten::make_intrusive( + dev_ctx.GetPlace()), + std::move(out_meta)); + Empty(dev_ctx, shape, &dense_out); + return dense_out; +} + +template +DenseTensor EmptyLike( + const ContextT& dev_ctx, + const DenseTensor& x, + DataType dtype = DataType::UNDEFINED, + Backend backend = Backend::UNDEFINED, // Is backend needed here? + DataLayout layout = DataLayout::UNDEFINED) { + auto out_meta = CreateLikeInferMeta(x.meta(), dtype, layout); + pten::DenseTensor dense_out( + pten::make_intrusive( + dev_ctx.GetPlace()), + std::move(out_meta)); + EmptyLike(dev_ctx, &dense_out); + return dense_out; +} + +template +DenseTensor Full(const ContextT& dev_ctx, + const ScalarArray& shape, + const Scalar& val, + DataType dtype = DataType::FLOAT32, + Backend backend = Backend::CPU, // Is backend needed here? + DataLayout layout = DataLayout::NCHW) { + auto out_meta = CreateInferMeta(shape, dtype, layout); + pten::DenseTensor dense_out( + pten::make_intrusive( + dev_ctx.GetPlace()), + std::move(out_meta)); + Full(dev_ctx, shape, val, &dense_out); + return dense_out; +} + template DenseTensor FullLike( const ContextT& dev_ctx, diff --git a/paddle/pten/kernels/empty_kernel.cc b/paddle/pten/kernels/empty_kernel.cc new file mode 100644 index 0000000000000000000000000000000000000000..4c6d8706e0ff3e6edb03e68158b339f561ca543a --- /dev/null +++ b/paddle/pten/kernels/empty_kernel.cc @@ -0,0 +1,80 @@ +/* Copyright (c) 2021 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/pten/kernels/empty_kernel.h" + +#include "paddle/pten/backends/all_context.h" +#include "paddle/pten/core/kernel_registry.h" + +namespace pten { + +template +void Empty(const ContextT& dev_ctx, + const ScalarArray& shape, + DenseTensor* out) { + out->Resize(paddle::framework::make_ddim(shape.GetData())); +} + +template +void EmptyLike(const ContextT& dev_ctx, DenseTensor* out) { + out->mutable_data(); +} + +} // namespace pten + +PT_REGISTER_CTX_KERNEL(empty, + CPU, + ALL_LAYOUT, + pten::Empty, + bool, + int, + int64_t, + float, + double, + paddle::platform::float16) {} + +PT_REGISTER_CTX_KERNEL(empty_like, + CPU, + ALL_LAYOUT, + pten::EmptyLike, + bool, + int, + int64_t, + float, + double, + paddle::platform::float16) {} + +#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP) +PT_REGISTER_CTX_KERNEL(empty, + GPU, + ALL_LAYOUT, + pten::Empty, + bool, + int, + int64_t, + float, + double, + paddle::platform::float16) {} + +PT_REGISTER_CTX_KERNEL(empty_like, + GPU, + ALL_LAYOUT, + pten::EmptyLike, + bool, + int, + int64_t, + float, + double, + paddle::platform::float16) {} +#endif diff --git a/paddle/pten/kernels/empty_kernel.h b/paddle/pten/kernels/empty_kernel.h new file mode 100644 index 0000000000000000000000000000000000000000..7aa5a27765a198e071d558d51a6b375e5eb54498 --- /dev/null +++ b/paddle/pten/kernels/empty_kernel.h @@ -0,0 +1,28 @@ +// Copyright (c) 2021 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. + +#pragma once + +#include "paddle/pten/common/scalar_array.h" +#include "paddle/pten/core/dense_tensor.h" + +namespace pten { + +template +void Empty(const ContextT& dev_ctx, const ScalarArray& shape, DenseTensor* out); + +template +void EmptyLike(const ContextT& dev_ctx, DenseTensor* out); + +} // namespace pten diff --git a/paddle/pten/kernels/full_kernel.h b/paddle/pten/kernels/full_kernel.h index f8abb9436679b19260ee28423d706019b7bfd764..d1139cf9ecefebf30d8c7fcdc1f3c23670c7f717 100644 --- a/paddle/pten/kernels/full_kernel.h +++ b/paddle/pten/kernels/full_kernel.h @@ -14,7 +14,6 @@ #pragma once -#include "paddle/pten/backends/cpu/cpu_context.h" #include "paddle/pten/common/scalar.h" #include "paddle/pten/common/scalar_array.h" #include "paddle/pten/core/dense_tensor.h" diff --git a/paddle/pten/tests/api/CMakeLists.txt b/paddle/pten/tests/api/CMakeLists.txt index e85eb4c3294f199137ac4bf223c31d4261fc9ebc..bb1eab2c095518ba8d1f9e7f18cd60f73be2e69b 100644 --- a/paddle/pten/tests/api/CMakeLists.txt +++ b/paddle/pten/tests/api/CMakeLists.txt @@ -12,6 +12,7 @@ cc_test(test_framework_place_utils storage SRCS test_place_utils.cc DEPS pten_ap cc_test(test_mean_api SRCS test_mean_api.cc DEPS pten_tensor pten_api pten_api_utils) cc_test(test_dot_api SRCS test_dot_api.cc DEPS pten_tensor pten_api pten_api_utils) cc_test(test_matmul_api SRCS test_matmul_api.cc DEPS pten_tensor pten_api pten_api_utils) +cc_test(test_empty_api SRCS test_empty_api.cc DEPS pten_tensor pten_api pten_api_utils) cc_test(test_fill_api SRCS test_fill_api.cc DEPS pten_tensor pten_api pten_api_utils) cc_test(test_flatten_api SRCS test_flatten_api.cc DEPS pten_tensor pten_api pten_api_utils) cc_test(test_elementwise_api SRCS test_elementwise_api.cc DEPS pten_tensor pten_api pten_api_utils) diff --git a/paddle/pten/tests/api/test_empty_api.cc b/paddle/pten/tests/api/test_empty_api.cc new file mode 100644 index 0000000000000000000000000000000000000000..fcc01ad8a71720b22cd82931e6219008b45c39d7 --- /dev/null +++ b/paddle/pten/tests/api/test_empty_api.cc @@ -0,0 +1,127 @@ +/* Copyright (c) 2021 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 +#include + +#include "paddle/pten/api/include/api.h" + +#include "paddle/pten/api/lib/utils/allocator.h" +#include "paddle/pten/core/dense_tensor.h" +#include "paddle/pten/core/kernel_registry.h" + +namespace paddle { +namespace tests { + +namespace framework = paddle::framework; +using DDim = paddle::framework::DDim; + +// TODO(chenweihang): Remove this test after the API is used in the dygraph +TEST(API, empty_like) { + // 1. create tensor + const auto alloc = std::make_shared( + paddle::platform::CPUPlace()); + auto dense_x = std::make_shared( + alloc, + pten::DenseTensorMeta(pten::DataType::FLOAT32, + framework::make_ddim({3, 2}), + pten::DataLayout::NCHW)); + + paddle::experimental::Tensor x(dense_x); + + // 2. test API + auto out = paddle::experimental::empty_like(x, pten::DataType::FLOAT32); + + // 3. check result + ASSERT_EQ(out.dims().size(), 2); + ASSERT_EQ(out.dims()[0], 3); + ASSERT_EQ(out.numel(), 6); + ASSERT_EQ(out.is_cpu(), true); + ASSERT_EQ(out.type(), pten::DataType::FLOAT32); + ASSERT_EQ(out.layout(), pten::DataLayout::NCHW); + ASSERT_EQ(out.initialized(), true); +} + +TEST(API, empty1) { + // 1. create tensor + const auto alloc = std::make_shared( + paddle::platform::CPUPlace()); + + auto dense_shape = std::make_shared( + alloc, + pten::DenseTensorMeta(pten::DataType::INT64, + framework::make_ddim({2}), + pten::DataLayout::NCHW)); + auto* shape_data = dense_shape->mutable_data(); + shape_data[0] = 2; + shape_data[1] = 3; + + paddle::experimental::Tensor tensor_shape(dense_shape); + + // 2. test API + auto out = paddle::experimental::empty(tensor_shape, pten::DataType::FLOAT32); + + // 3. check result + ASSERT_EQ(out.shape().size(), 2UL); + ASSERT_EQ(out.shape()[0], 2); + ASSERT_EQ(out.numel(), 6); + ASSERT_EQ(out.is_cpu(), true); + ASSERT_EQ(out.type(), pten::DataType::FLOAT32); + ASSERT_EQ(out.layout(), pten::DataLayout::NCHW); + ASSERT_EQ(out.initialized(), true); +} + +TEST(API, empty2) { + const auto alloc = std::make_shared( + paddle::platform::CPUPlace()); + + auto dense_scalar = std::make_shared( + alloc, + pten::DenseTensorMeta(pten::DataType::INT32, + framework::make_ddim({1}), + pten::DataLayout::NCHW)); + dense_scalar->mutable_data()[0] = 2; + + paddle::experimental::Tensor shape_scalar1(dense_scalar); + paddle::experimental::Tensor shape_scalar2(dense_scalar); + std::vector list_shape{shape_scalar1, + shape_scalar2}; + + auto out = paddle::experimental::empty(list_shape, pten::DataType::FLOAT32); + + ASSERT_EQ(out.shape().size(), 2UL); + ASSERT_EQ(out.shape()[0], 2); + ASSERT_EQ(out.numel(), 4); + ASSERT_EQ(out.is_cpu(), true); + ASSERT_EQ(out.type(), pten::DataType::FLOAT32); + ASSERT_EQ(out.layout(), pten::DataLayout::NCHW); + ASSERT_EQ(out.initialized(), true); +} + +TEST(API, empty3) { + std::vector vector_shape{2, 3}; + + auto out = paddle::experimental::empty(vector_shape, pten::DataType::INT32); + + ASSERT_EQ(out.shape().size(), 2UL); + ASSERT_EQ(out.shape()[0], 2); + ASSERT_EQ(out.numel(), 6); + ASSERT_EQ(out.is_cpu(), true); + ASSERT_EQ(out.type(), pten::DataType::INT32); + ASSERT_EQ(out.layout(), pten::DataLayout::NCHW); + ASSERT_EQ(out.initialized(), true); +} + +} // namespace tests +} // namespace paddle diff --git a/paddle/pten/tests/kernels/CMakeLists.txt b/paddle/pten/tests/kernels/CMakeLists.txt index 3a626aad2deb5dd8a9f3a09f3f5417b9394a36b0..5f14554a0cceeb3a7abce4f0f128b9c9c5254d64 100644 --- a/paddle/pten/tests/kernels/CMakeLists.txt +++ b/paddle/pten/tests/kernels/CMakeLists.txt @@ -1,6 +1,6 @@ cc_test(test_copy_dev_api SRCS test_copy_dev_api.cc DEPS pten pten_api_utils) cc_test(test_dot_dev_api SRCS test_dot_dev_api.cc DEPS pten pten_api_utils) -cc_test(test_fill_dev_api SRCS test_fill_dev_api.cc DEPS pten pten_api_utils) +cc_test(test_creation_dev_api SRCS test_creation_dev_api.cc DEPS pten pten_api_utils) cc_test(test_flatten_dev_api SRCS test_flatten_dev_api.cc DEPS pten pten_api_utils) cc_test(test_mean_dev_api SRCS test_mean_dev_api.cc DEPS pten pten_api_utils) cc_test(test_scale_dev_api SRCS test_scale_dev_api.cc DEPS pten pten_api_utils) diff --git a/paddle/pten/tests/kernels/test_creation_dev_api.cc b/paddle/pten/tests/kernels/test_creation_dev_api.cc new file mode 100644 index 0000000000000000000000000000000000000000..8469b94b797c8757b51aeaa8814e151aacfb9778 --- /dev/null +++ b/paddle/pten/tests/kernels/test_creation_dev_api.cc @@ -0,0 +1,141 @@ +/* Copyright (c) 2021 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 +#include + +#include "paddle/pten/include/creation.h" + +#include "paddle/pten/api/lib/utils/allocator.h" +#include "paddle/pten/core/dense_tensor.h" +#include "paddle/pten/core/kernel_registry.h" + +namespace pten { +namespace tests { + +namespace framework = paddle::framework; +using DDim = paddle::framework::DDim; + +TEST(DEV_API, empty) { + // 1. create input + paddle::platform::DeviceContextPool& pool = + paddle::platform::DeviceContextPool::Instance(); + auto* dev_ctx = pool.Get(paddle::platform::CPUPlace()); + + // 2. test API + auto out = pten::Empty( + *(static_cast(dev_ctx)), + {3, 2}, + pten::DataType::INT32); + + // 3. check result + ASSERT_EQ(out.dims().size(), 2); + ASSERT_EQ(out.dims()[0], 3); + ASSERT_EQ(out.numel(), 6); + ASSERT_EQ(out.meta().dtype, pten::DataType::INT32); + ASSERT_EQ(out.meta().layout, pten::DataLayout::NCHW); +} + +TEST(DEV_API, empty_like) { + // 1. create tensor + const auto alloc = std::make_shared( + paddle::platform::CPUPlace()); + pten::DenseTensor dense_x(alloc, + pten::DenseTensorMeta(pten::DataType::FLOAT32, + framework::make_ddim({3, 2}), + pten::DataLayout::NCHW)); + auto* dense_x_data = dense_x.mutable_data(); + dense_x_data[0] = 0; + + paddle::platform::DeviceContextPool& pool = + paddle::platform::DeviceContextPool::Instance(); + auto* dev_ctx = pool.Get(paddle::platform::CPUPlace()); + + // 2. test API + auto out = pten::EmptyLike( + *(static_cast(dev_ctx)), dense_x); + + // 3. check result + ASSERT_EQ(out.dims().size(), 2); + ASSERT_EQ(out.dims()[0], 3); + ASSERT_EQ(out.numel(), 6); + ASSERT_EQ(out.meta().dtype, pten::DataType::FLOAT32); + ASSERT_EQ(out.meta().layout, pten::DataLayout::NCHW); +} + +TEST(DEV_API, full) { + // 1. create input + float val = 1.0; + + paddle::platform::DeviceContextPool& pool = + paddle::platform::DeviceContextPool::Instance(); + auto* dev_ctx = pool.Get(paddle::platform::CPUPlace()); + + // 2. test API + auto out = pten::Full( + *(static_cast(dev_ctx)), + {3, 2}, + val, + pten::DataType::FLOAT32); + + // 3. check result + ASSERT_EQ(out.dims().size(), 2); + ASSERT_EQ(out.dims()[0], 3); + ASSERT_EQ(out.numel(), 6); + ASSERT_EQ(out.meta().dtype, pten::DataType::FLOAT32); + ASSERT_EQ(out.meta().layout, pten::DataLayout::NCHW); + + auto* actual_result = out.data(); + for (auto i = 0; i < 6; i++) { + ASSERT_NEAR(actual_result[i], val, 1e-6f); + } +} + +TEST(DEV_API, full_like) { + // 1. create tensor + const auto alloc = std::make_shared( + paddle::platform::CPUPlace()); + pten::DenseTensor dense_x(alloc, + pten::DenseTensorMeta(pten::DataType::FLOAT32, + framework::make_ddim({3, 2}), + pten::DataLayout::NCHW)); + auto* dense_x_data = dense_x.mutable_data(); + dense_x_data[0] = 0; + float val = 1.0; + + paddle::platform::DeviceContextPool& pool = + paddle::platform::DeviceContextPool::Instance(); + auto* dev_ctx = pool.Get(paddle::platform::CPUPlace()); + + // 2. test API + auto out = pten::FullLike( + *(static_cast(dev_ctx)), + dense_x, + val); + + // 3. check result + ASSERT_EQ(out.dims().size(), 2); + ASSERT_EQ(out.dims()[0], 3); + ASSERT_EQ(out.numel(), 6); + ASSERT_EQ(out.meta().dtype, pten::DataType::FLOAT32); + ASSERT_EQ(out.meta().layout, pten::DataLayout::NCHW); + + auto* actual_result = out.data(); + for (auto i = 0; i < 6; i++) { + ASSERT_NEAR(actual_result[i], val, 1e-6f); + } +} + +} // namespace tests +} // namespace pten diff --git a/paddle/pten/tests/kernels/test_fill_dev_api.cc b/paddle/pten/tests/kernels/test_fill_dev_api.cc deleted file mode 100644 index 9a8b1f94e731b5a53f9d811cae20707439429002..0000000000000000000000000000000000000000 --- a/paddle/pten/tests/kernels/test_fill_dev_api.cc +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2021 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 -#include - -#include "paddle/pten/include/creation.h" - -#include "paddle/pten/api/lib/utils/allocator.h" -#include "paddle/pten/core/dense_tensor.h" -#include "paddle/pten/core/kernel_registry.h" - -namespace pten { -namespace tests { - -namespace framework = paddle::framework; -using DDim = paddle::framework::DDim; - -TEST(DEV_API, fill_any_like) { - // 1. create tensor - const auto alloc = std::make_shared( - paddle::platform::CPUPlace()); - pten::DenseTensor dense_x(alloc, - pten::DenseTensorMeta(pten::DataType::FLOAT32, - framework::make_ddim({3, 2}), - pten::DataLayout::NCHW)); - auto* dense_x_data = dense_x.mutable_data(); - dense_x_data[0] = 0; - float val = 1.0; - - paddle::platform::DeviceContextPool& pool = - paddle::platform::DeviceContextPool::Instance(); - auto* dev_ctx = pool.Get(paddle::platform::CPUPlace()); - - // 2. test API - auto out = pten::FullLike( - *(static_cast(dev_ctx)), - dense_x, - val); - - // 3. check result - ASSERT_EQ(out.dims().size(), 2); - ASSERT_EQ(out.dims()[0], 3); - ASSERT_EQ(out.numel(), 6); - ASSERT_EQ(out.meta().dtype, pten::DataType::FLOAT32); - ASSERT_EQ(out.meta().layout, pten::DataLayout::NCHW); - - auto* actual_result = out.data(); - for (auto i = 0; i < 6; i++) { - ASSERT_NEAR(actual_result[i], val, 1e-6f); - } -} - -} // namespace tests -} // namespace pten diff --git a/python/paddle/utils/code_gen/api.yaml b/python/paddle/utils/code_gen/api.yaml index 5022abdb36737cbca003c0759d6d51b422c2247d..8aacaec69c8f3bc53ed89895885ab8c66443624f 100644 --- a/python/paddle/utils/code_gen/api.yaml +++ b/python/paddle/utils/code_gen/api.yaml @@ -36,6 +36,32 @@ kernel : func : dot +- api : empty + args : (const ScalarArray& shape, DataType dtype=DataType::FLOAT32, Backend place=Backend::CPU, DataLayout layout=DataLayout::NCHW) + output: Tensor + infer_meta : + func : CreateInferMeta + param : [shape, dtype, layout] + kernel : + func : empty + param : [shape] + data_type : dtype + backend : place + layout : layout + +- api : empty_like + args : (const Tensor& x, DataType dtype = DataType::UNDEFINED, Backend place = Backend::UNDEFINED, DataLayout layout = DataLayout::UNDEFINED) + output: Tensor + infer_meta : + func : CreateLikeInferMeta + param : [x, dtype, layout] + kernel : + func : empty_like + param : [] + data_type : dtype > x + backend : place > x + layout : layout > x + - api : flatten args : (const Tensor& x, int start_axis, int stop_axis) output : Tensor diff --git a/python/paddle/utils/code_gen/api_gen.py b/python/paddle/utils/code_gen/api_gen.py index e1822a62b8c51794e616ae38de424e136754429f..72bf26c57dd5ad475e3ac9a10121d14a895828f7 100644 --- a/python/paddle/utils/code_gen/api_gen.py +++ b/python/paddle/utils/code_gen/api_gen.py @@ -43,12 +43,11 @@ class API: if 'data_type' not in self.kernel or len(self.kernel[ 'data_type']) == 0: self.kernel['data_type'] = None - if 'param' not in self.kernel or len(self.kernel['param']) == 0: + if 'param' not in self.kernel: self.kernel['param'] = None self.infer_meta = api_item_yaml['infer_meta'] - if 'param' not in self.infer_meta or len(self.infer_meta[ - 'param']) == 0: + if 'param' not in self.infer_meta: self.infer_meta['param'] = None def parse_args(self, args_str):