diff --git a/paddle/phi/CMakeLists.txt b/paddle/phi/CMakeLists.txt index 0595ea4d8bddf936f1f486c0b4eb5ebb6390129d..58ad42ddd1ff89866a1f5c2fbb59565b68105853 100644 --- a/paddle/phi/CMakeLists.txt +++ b/paddle/phi/CMakeLists.txt @@ -23,7 +23,7 @@ add_subdirectory(tools) add_subdirectory(tests) # make an unity target for compile deps -set(PHI_DEPS convert_utils dense_tensor phi_context kernel_factory kernel_context arg_map_context infermeta lod_utils op_compat_infos sparse_csr_tensor sparse_coo_tensor string_tensor api_scalar) +set(PHI_DEPS convert_utils dense_tensor phi_context kernel_factory kernel_context arg_map_context infermeta lod_utils op_compat_infos sparse_csr_tensor sparse_coo_tensor string_tensor api_scalar api_int_array) get_property(phi_kernels GLOBAL PROPERTY PHI_KERNELS) set(PHI_DEPS ${PHI_DEPS} ${phi_kernels}) diff --git a/paddle/phi/api/lib/CMakeLists.txt b/paddle/phi/api/lib/CMakeLists.txt index ddeb073046bf1230e4de1df2ac15da3f615141eb..2844bd67fab2f56fedd55189aea738cbc20e7e82 100644 --- a/paddle/phi/api/lib/CMakeLists.txt +++ b/paddle/phi/api/lib/CMakeLists.txt @@ -176,3 +176,4 @@ cc_library(strings_api SRCS ${strings_api_source_file} DEPS phi_tensor_raw phi k cc_library(phi_tensor SRCS tensor_method.cc DEPS phi_tensor_raw phi_function_api api_gen_utils kernel_dispatch infermeta sparse_api strings_api) cc_library(tensor_copy SRCS tensor_copy.cc DEPS phi_tensor_raw copy_kernel kernel_dispatch api_gen_utils) cc_library(api_scalar SRCS scalar.cc DEPS tensor_copy) +cc_library(api_int_array SRCS int_array.cc DEPS tensor_copy) diff --git a/paddle/phi/api/lib/int_array.cc b/paddle/phi/api/lib/int_array.cc new file mode 100644 index 0000000000000000000000000000000000000000..503fc8184abf68afe0f1e8b9d5b67f79fef949f7 --- /dev/null +++ b/paddle/phi/api/lib/int_array.cc @@ -0,0 +1,72 @@ +/* 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/common/int_array.h" + +#include "paddle/phi/api/lib/tensor_copy.h" +#include "paddle/phi/common/place.h" + +namespace paddle { +namespace experimental { + +template <> +IntArrayBase::IntArrayBase(const Tensor& tensor) { // NOLINT + is_from_tensor_ = true; + if (tensor.place().GetType() == phi::AllocationType::CPU) { + AssignDataFromTensor(tensor); + } else { + Tensor tensor_tmp; + copy(tensor, phi::CPUPlace(), true, &tensor_tmp); + AssignDataFromTensor(tensor_tmp); + } +} + +template <> +IntArrayBase::IntArrayBase(const std::vector& tensor_list) { + is_from_tensor_ = true; + + for (size_t i = 0; i < tensor_list.size(); ++i) { + DataType data_type = tensor_list[i].dtype(); + switch (data_type) { + case DataType::INT32: + if (tensor_list[i].place().GetType() == AllocationType::CPU) { + array_.push_back(*tensor_list[i].template data()); + } else { + Tensor tensor_tmp; + copy(tensor_list[i], phi::CPUPlace(), true, &tensor_tmp); + array_.push_back(*tensor_tmp.template data()); + } + break; + case DataType::INT64: + if (tensor_list[i].place().GetType() == AllocationType::CPU) { + array_.push_back(*tensor_list[i].template data()); + } else { + Tensor tensor_tmp; + copy(tensor_list[i], phi::CPUPlace(), true, &tensor_tmp); + array_.push_back(*tensor_tmp.template data()); + } + break; + default: + PD_THROW( + "Data type error. Currently, The data type of IntArrayBase " + "only supports Tensor with int32 and int64, " + "but now received `", + data_type, + "`."); + } + } +} + +} // namespace experimental +} // namespace paddle diff --git a/paddle/phi/api/lib/utils/CMakeLists.txt b/paddle/phi/api/lib/utils/CMakeLists.txt index de97e7516f61938068a12d781dcc950e51863740..5689b2d43a4f2280d8ac605fb3c358145961e61e 100644 --- a/paddle/phi/api/lib/utils/CMakeLists.txt +++ b/paddle/phi/api/lib/utils/CMakeLists.txt @@ -1,2 +1,2 @@ cc_library(phi_api_utils SRCS storage.cc tensor_utils.cc DEPS -tensor_base convert_utils dense_tensor lod_tensor selected_rows_utils place var_type_traits string_tensor scalar) +tensor_base convert_utils dense_tensor lod_tensor selected_rows_utils place var_type_traits string_tensor int_array scalar) diff --git a/paddle/phi/api/lib/utils/tensor_utils.cc b/paddle/phi/api/lib/utils/tensor_utils.cc index 5a6f1b1a7ee0cd7c2dee9e52d79a3efc50596c87..c9fb2d3734edc0c4797f2ce6f6c379c4c3076b17 100644 --- a/paddle/phi/api/lib/utils/tensor_utils.cc +++ b/paddle/phi/api/lib/utils/tensor_utils.cc @@ -67,16 +67,9 @@ phi::IntArray MakePhiIntArray(const paddle::framework::Tensor& src) { } phi::IntArray MakePhiIntArrayFromVar(const framework::Variable& variable) { - auto expected_place = phi::TransToPhiPlace(phi::Backend::CPU); if (variable.IsType()) { const auto& tensor = variable.Get(); - if (!platform::is_same_place(tensor.place(), expected_place)) { - framework::LoDTensor tmp_tensor; - framework::TensorCopySync(tensor, expected_place, &tmp_tensor); - return MakePhiIntArray(tmp_tensor); - } else { - return MakePhiIntArray(tensor); - } + return MakePhiIntArray(tensor); } else { PADDLE_THROW(platform::errors::Unimplemented( "Unsupport casting input `%s` type to IntArray when call pt " diff --git a/paddle/phi/common/CMakeLists.txt b/paddle/phi/common/CMakeLists.txt index aa839eab587cbe74f6f49be4edf9679c001e7b01..b1ca4d1f8a8c6b1bc3ad0e369e7aab994e282c4a 100644 --- a/paddle/phi/common/CMakeLists.txt +++ b/paddle/phi/common/CMakeLists.txt @@ -1,2 +1,3 @@ cc_library(phi_place SRCS place.cc) cc_library(scalar SRCS scalar.cc DEPS phi_enforce tensor) +cc_library(int_array SRCS int_array.cc DEPS phi_enforce tensor) diff --git a/paddle/phi/common/int_array.cc b/paddle/phi/common/int_array.cc new file mode 100644 index 0000000000000000000000000000000000000000..daed2b6625a9e2837d84cbbd7762740302f425a1 --- /dev/null +++ b/paddle/phi/common/int_array.cc @@ -0,0 +1,77 @@ +/* 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/common/int_array.h" + +#include "paddle/phi/common/place.h" + +#include "paddle/fluid/framework/tensor_util.h" + +namespace paddle { +namespace experimental { + +template <> +IntArrayBase::IntArrayBase( + const phi::DenseTensor& tensor) { // NOLINT + is_from_tensor_ = true; + if (tensor.place().GetType() == AllocationType::CPU) { + AssignDataFromTensor(tensor); + } else { + phi::DenseTensor tensor_tmp; + paddle::framework::TensorCopySync(tensor, CPUPlace(), &tensor_tmp); + AssignDataFromTensor(tensor_tmp); + } +} + +template <> +IntArrayBase::IntArrayBase( + const std::vector& tensor_list) { + is_from_tensor_ = true; + + for (size_t i = 0; i < tensor_list.size(); ++i) { + DataType data_type = tensor_list[i].dtype(); + switch (data_type) { + case DataType::INT32: + if (tensor_list[i].place().GetType() == AllocationType::CPU) { + array_.push_back(*tensor_list[i].template data()); + } else { + phi::DenseTensor tensor_tmp; + paddle::framework::TensorCopySync( + tensor_list[i], CPUPlace(), &tensor_tmp); + array_.push_back(*tensor_tmp.template data()); + } + break; + case DataType::INT64: + if (tensor_list[i].place().GetType() == AllocationType::CPU) { + array_.push_back(*tensor_list[i].template data()); + } else { + phi::DenseTensor tensor_tmp; + paddle::framework::TensorCopySync( + tensor_list[i], CPUPlace(), &tensor_tmp); + array_.push_back(*tensor_tmp.template data()); + } + break; + default: + PD_THROW( + "Data type error. Currently, The data type of IntArrayBase " + "only supports Tensor with int32 and int64, " + "but now received `", + data_type, + "`."); + } + } +} + +} // namespace experimental +} // namespace paddle diff --git a/paddle/phi/common/int_array.h b/paddle/phi/common/int_array.h index f9d07249e0fc9a4651932de32d9de4410c14b540..91b9ace136bc22943b8520220a0c09fc760fc958 100644 --- a/paddle/phi/common/int_array.h +++ b/paddle/phi/common/int_array.h @@ -48,50 +48,10 @@ class IntArrayBase { void SetFromTensor(bool val) { is_from_tensor_ = val; } // The Tensor must have one dim - IntArrayBase(const T& tensor) { // NOLINT - is_from_tensor_ = true; - size_t n = tensor.numel(); - array_.reserve(n); - switch (tensor.dtype()) { - case DataType::INT32: - AssignData(tensor.template data(), n); - break; - case DataType::INT64: - AssignData(tensor.template data(), n); - break; - default: - PD_THROW( - "Data type error. Currently, The data type of IntArrayBase " - "only supports Tensor with int32 and int64, " - "but now received `", - tensor.dtype(), - "`."); - } - } + IntArrayBase(const T& tensor); // NOLINT // The Tensor in vec must have only one element - IntArrayBase(const std::vector& tensor_list) { // NOLINT - is_from_tensor_ = true; - - for (size_t i = 0; i < tensor_list.size(); ++i) { - DataType data_type = tensor_list[i].dtype(); - switch (data_type) { - case DataType::INT32: - array_.push_back(*tensor_list[i].template data()); - break; - case DataType::INT64: - array_.push_back(*tensor_list[i].template data()); - break; - default: - PD_THROW( - "Data type error. Currently, The data type of IntArrayBase " - "only supports Tensor with int32 and int64, " - "but now received `", - data_type, - "`."); - } - } - } + IntArrayBase(const std::vector& tensor_list); // NOLINT template IntArrayBase(const IntArrayBase& other) : array_(other.GetData()) {} @@ -114,6 +74,26 @@ class IntArrayBase { } } + void AssignDataFromTensor(const T& tensor) { + size_t n = tensor.numel(); + array_.reserve(n); + switch (tensor.dtype()) { + case DataType::INT32: + AssignData(tensor.template data(), n); + break; + case DataType::INT64: + AssignData(tensor.template data(), n); + break; + default: + PD_THROW( + "Data type error. Currently, The data type of IntArrayBase " + "only supports Tensor with int32 and int64, " + "but now received `", + tensor.dtype(), + "`."); + } + } + private: // TODO(zhangyunfei) Replace std::vector with a more efficient container // structure. diff --git a/paddle/phi/tests/common/CMakeLists.txt b/paddle/phi/tests/common/CMakeLists.txt index ca6d20045d1714d8ed7c00648d3626254099b414..150336a1ed694e604103ccb9b294b6837a45133f 100644 --- a/paddle/phi/tests/common/CMakeLists.txt +++ b/paddle/phi/tests/common/CMakeLists.txt @@ -2,6 +2,7 @@ cc_test(phi_test_backend SRCS test_backend.cc DEPS gtest) cc_test(phi_test_data_layout SRCS test_data_layout.cc DEPS gtest) cc_test(phi_test_data_type SRCS test_data_type.cc DEPS gtest) cc_test(phi_test_place SRCS test_place.cc DEPS phi_place) +cc_test(phi_test_int_array SRCS test_int_array.cc DEPS int_array api_int_array phi phi_api) if (WITH_GPU) nv_test(phi_test_scalar SRCS test_scalar.cu DEPS scalar api_scalar) endif() diff --git a/paddle/phi/tests/common/test_int_array.cc b/paddle/phi/tests/common/test_int_array.cc new file mode 100644 index 0000000000000000000000000000000000000000..b6c4f2b1ea8e3472218424468031edd5f2a9de3a --- /dev/null +++ b/paddle/phi/tests/common/test_int_array.cc @@ -0,0 +1,159 @@ +/* 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/api/include/api.h" + +#include "paddle/phi/api/include/context_pool.h" +#include "paddle/phi/backends/cpu/cpu_context.h" +#include "paddle/phi/backends/gpu/gpu_context.h" +#include "paddle/phi/common/int_array.h" +#include "paddle/phi/kernels/full_kernel.h" + +#include "paddle/phi/core/kernel_registry.h" + +#include "gtest/gtest.h" + +PD_DECLARE_KERNEL(full, CPU, ALL_LAYOUT); +#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP) +PD_DECLARE_KERNEL(full, GPU, ALL_LAYOUT); +#endif + +namespace phi { +namespace tests { + +TEST(IntArray, ConstructFromCPUDenseTensor) { + auto& pool = paddle::experimental::DeviceContextPool::Instance(); + const auto* dev_ctx = + static_cast(pool.Get(CPUPlace())); + phi::DenseTensor shape = Full(*dev_ctx, {2}, 3); + phi::DenseTensor out = Full(*dev_ctx, shape, 1); + ASSERT_EQ(out.dims().size(), 2); + ASSERT_EQ(out.dims()[0], 3); + ASSERT_EQ(out.dims()[1], 3); + ASSERT_EQ(out.numel(), 9); +} + +TEST(IntArray, ConstructFromCPUDenseTensorVector) { + auto& pool = paddle::experimental::DeviceContextPool::Instance(); + const auto* dev_ctx = + static_cast(pool.Get(CPUPlace())); + phi::DenseTensor shape0 = Full(*dev_ctx, {1}, 3); + phi::DenseTensor shape1 = Full(*dev_ctx, {1}, 3); + std::vector shape{shape0, shape1}; + phi::DenseTensor out = Full(*dev_ctx, shape, 1); + ASSERT_EQ(out.dims().size(), 2); + ASSERT_EQ(out.dims()[0], 3); + ASSERT_EQ(out.dims()[1], 3); + ASSERT_EQ(out.numel(), 9); +} + +TEST(IntArray, ConstructFromCPUTensor) { + auto shape = paddle::experimental::full({2}, 3, DataType::INT64); + auto out = paddle::experimental::full(shape, 1); + ASSERT_EQ(out.dims().size(), 2); + ASSERT_EQ(out.dims()[0], 3); + ASSERT_EQ(out.dims()[1], 3); + ASSERT_EQ(out.numel(), 9); +} + +TEST(IntArray, ConstructFromCPUTensorVector) { + auto shape0 = paddle::experimental::full({2}, 3, DataType::INT64); + auto shape1 = paddle::experimental::full({2}, 3, DataType::INT32); + + std::vector shape{shape0, shape0}; + auto out = paddle::experimental::full(shape, 1); + + std::vector shape_new{shape0, shape1}; + auto out1 = paddle::experimental::full(shape_new, 1); + + ASSERT_EQ(out.dims().size(), 2); + ASSERT_EQ(out.dims()[0], 3); + ASSERT_EQ(out.dims()[1], 3); + ASSERT_EQ(out.numel(), 9); + + ASSERT_EQ(out1.dims().size(), 2); + ASSERT_EQ(out1.dims()[0], 3); + ASSERT_EQ(out1.dims()[1], 3); + ASSERT_EQ(out1.numel(), 9); +} + +TEST(IntArray, ThrowException) { + auto shape = paddle::experimental::full({2}, 3, DataType::FLOAT32); + auto create_int_array = [&shape]() -> paddle::experimental::IntArray { + paddle::experimental::IntArray int_array{shape}; + return int_array; + }; + ASSERT_ANY_THROW(create_int_array()); +} + +#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP) +TEST(IntArray, ConstructFromGPUDenseTensor) { + auto& pool = paddle::experimental::DeviceContextPool::Instance(); + const auto* dev_ctx = + static_cast(pool.Get(GPUPlace())); + phi::DenseTensor shape = Full(*dev_ctx, {2}, 3); + phi::DenseTensor out = Full(*dev_ctx, shape, 1); + ASSERT_EQ(out.dims().size(), 2); + ASSERT_EQ(out.dims()[0], 3); + ASSERT_EQ(out.dims()[1], 3); + ASSERT_EQ(out.numel(), 9); +} + +TEST(IntArray, ConstructFromGPUDenseTensorVector) { + auto& pool = paddle::experimental::DeviceContextPool::Instance(); + const auto* dev_ctx = + static_cast(pool.Get(GPUPlace())); + phi::DenseTensor shape0 = Full(*dev_ctx, {1}, 3); + phi::DenseTensor shape1 = Full(*dev_ctx, {1}, 3); + std::vector shape{shape0, shape1}; + phi::DenseTensor out = Full(*dev_ctx, shape, 1); + ASSERT_EQ(out.dims().size(), 2); + ASSERT_EQ(out.dims()[0], 3); + ASSERT_EQ(out.dims()[1], 3); + ASSERT_EQ(out.numel(), 9); +} + +TEST(IntArray, ConstructFromGPUTensor) { + auto shape = paddle::experimental::full({2}, 3, DataType::INT64, GPUPlace()); + auto out = paddle::experimental::full(shape, 1); + ASSERT_EQ(out.dims().size(), 2); + ASSERT_EQ(out.dims()[0], 3); + ASSERT_EQ(out.dims()[1], 3); + ASSERT_EQ(out.numel(), 9); +} + +TEST(IntArray, ConstructFromGPUTensorVector) { + auto shape0 = paddle::experimental::full({2}, 3, DataType::INT64, GPUPlace()); + auto shape1 = paddle::experimental::full({2}, 3, DataType::INT32, GPUPlace()); + + std::vector shape{shape0, shape0}; + auto out = paddle::experimental::full(shape, 1); + + std::vector shape_new{shape0, shape1}; + auto out1 = paddle::experimental::full(shape_new, 1); + + ASSERT_EQ(out.dims().size(), 2); + ASSERT_EQ(out.dims()[0], 3); + ASSERT_EQ(out.dims()[1], 3); + ASSERT_EQ(out.numel(), 9); + + ASSERT_EQ(out1.dims().size(), 2); + ASSERT_EQ(out1.dims()[0], 3); + ASSERT_EQ(out1.dims()[1], 3); + ASSERT_EQ(out1.numel(), 9); +} +#endif + +} // namespace tests +} // namespace phi diff --git a/python/paddle/fluid/layers/tensor.py b/python/paddle/fluid/layers/tensor.py index a9b1fa6ff0205949170c52f36f81129af57fe015..b02c154584e9c8dca6f070de1b1c06346c296c02 100644 --- a/python/paddle/fluid/layers/tensor.py +++ b/python/paddle/fluid/layers/tensor.py @@ -760,8 +760,14 @@ def fill_constant(shape, dtype, value, force_cpu=False, out=None, name=None): place = _current_expected_place() if force_cpu: place = core.CPUPlace() + if isinstance(shape, (list, tuple)): + for item in shape: + if not isinstance(item, Variable): + shape = list( + map(lambda x: x.numpy().flat[0] if isinstance(x, Variable) else x, + shape)) + break - shape = utils.convert_shape_to_list(shape) if not isinstance(dtype, core.VarDesc.VarType): dtype = convert_np_dtype_to_dtype_(dtype) out = _C_ops.final_state_full(shape, float(value), dtype, place) diff --git a/python/paddle/fluid/tests/unittests/test_empty_op.py b/python/paddle/fluid/tests/unittests/test_empty_op.py index b8ff66a910ece4584be53baf1d194161fec0965a..371c59a1b8cce36cc4ecec73dd938250b1a0f3b4 100644 --- a/python/paddle/fluid/tests/unittests/test_empty_op.py +++ b/python/paddle/fluid/tests/unittests/test_empty_op.py @@ -232,28 +232,33 @@ class TestEmptyAPI(unittest.TestCase): name="shape_tensor_int32", shape=[2], dtype="int32") shape_tensor_int64 = fluid.data( name="shape_tensor_int64", shape=[2], dtype="int64") + shape_tensor_unknown = fluid.data( + name="shape_tensor_unknown", shape=[-1], dtype="int64") out_1 = paddle.empty(shape=[200, 3], dtype=dtype) out_2 = paddle.empty(shape=shape_tensor_int32, dtype=dtype) out_3 = paddle.empty(shape=shape_tensor_int64, dtype=dtype) out_4 = paddle.empty(shape=[200, positive_2_int32], dtype=dtype) out_5 = paddle.empty(shape=[200, positive_2_int64], dtype=dtype) + out_6 = paddle.empty(shape=shape_tensor_unknown, dtype=dtype) place = paddle.CPUPlace() exe = paddle.static.Executor(place) - res_1, res_2, res_3, res_4, res_5 = exe.run( + res_1, res_2, res_3, res_4, res_5, res_6 = exe.run( fluid.default_main_program(), feed={ "shape_tensor_int32": np.array([200, 3]).astype("int32"), "shape_tensor_int64": np.array([200, 3]).astype("int64"), + "shape_tensor_unknown": np.array([200, 3]).astype("int64"), }, - fetch_list=[out_1, out_2, out_3, out_4, out_5]) + fetch_list=[out_1, out_2, out_3, out_4, out_5, out_6]) self.__check_out__(res_1, dtype) self.__check_out__(res_2, dtype) self.__check_out__(res_3, dtype) self.__check_out__(res_4, dtype) self.__check_out__(res_5, dtype) + self.__check_out__(res_6, dtype) class TestEmptyError(unittest.TestCase): diff --git a/python/paddle/fluid/tests/unittests/test_full_op.py b/python/paddle/fluid/tests/unittests/test_full_op.py index 108469cf8a7323e3ae675c15e89bc1f6ba80c5f9..723c4609bc96b9b79db61f747053ba3d1e7315d7 100644 --- a/python/paddle/fluid/tests/unittests/test_full_op.py +++ b/python/paddle/fluid/tests/unittests/test_full_op.py @@ -80,8 +80,10 @@ class TestFullAPI(unittest.TestCase): with fluid.dygraph.base.guard(): with _test_eager_guard(): positive_2_int32 = fluid.layers.fill_constant([1], "int32", 2) - positive_2_int64 = fluid.layers.fill_constant([1], "int64", 2) + positive_4_int64 = fluid.layers.fill_constant([1], "int64", 4, + True) + out_1 = paddle.full( shape=[1, 2], dtype="float32", fill_value=1.1) @@ -108,8 +110,19 @@ class TestFullAPI(unittest.TestCase): shape=[1], dtype=np.float32, value=1.1) out_7 = paddle.full( shape=[1, 2], dtype=np.float32, fill_value=val) + + out_8 = paddle.full( + shape=positive_2_int32, dtype="float32", fill_value=1.1) + + out_9 = paddle.full( + shape=[ + positive_2_int32, positive_2_int64, positive_4_int64 + ], + dtype="float32", + fill_value=1.1) + # test for numpy.float64 as fill_value - out_8 = paddle.full_like( + out_10 = paddle.full_like( out_7, dtype=np.float32, fill_value=np.abs(1.1)) assert np.array_equal( @@ -133,8 +146,12 @@ class TestFullAPI(unittest.TestCase): assert np.array_equal( out_7, np.full( [1, 2], 1.1, dtype="float32")) + assert np.array_equal(out_8, np.full([2], 1.1, dtype="float32")) + assert np.array_equal( + out_9, np.full( + [2, 2, 4], 1.1, dtype="float32")) assert np.array_equal( - out_8, np.full( + out_10, np.full( [1, 2], 1.1, dtype="float32")) diff --git a/python/paddle/tensor/manipulation.py b/python/paddle/tensor/manipulation.py index 127aa71137dfff2db154336a75abc237adcb2594..4802145bc3d8c35908a86bf67f2d76dfb966dc81 100755 --- a/python/paddle/tensor/manipulation.py +++ b/python/paddle/tensor/manipulation.py @@ -1530,8 +1530,6 @@ def roll(x, shifts, axis=None, name=None): axis = [] if in_dygraph_mode(): - if isinstance(shifts, paddle.Tensor): - shifts = shifts.cpu() return _C_ops.final_state_roll(x, shifts, axis) if _in_legacy_dygraph():