From 2ed0196047cebedf3ab5dac047d6b052d69bbbdb Mon Sep 17 00:00:00 2001 From: Weilong Wu Date: Tue, 19 Apr 2022 09:17:32 +0800 Subject: [PATCH] [Eager] Fix numpy interface for constructing empty tensor (#41904) * [Eager] Fix numpy interface for constructing empty tensor * Fix CI, construct empty tensor * Modify empty tensor's shape from [] to [0] * Add more test for constructing empty tensor --- paddle/fluid/pybind/eager.cc | 4 ++-- paddle/fluid/pybind/eager_method.cc | 11 +++++++++++ paddle/phi/api/lib/tensor.cc | 3 --- .../fluid/tests/unittests/test_egr_python_api.py | 2 +- python/paddle/fluid/tests/unittests/test_var_base.py | 7 +++++++ 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/paddle/fluid/pybind/eager.cc b/paddle/fluid/pybind/eager.cc index fa66e55e9c5..8695928205b 100644 --- a/paddle/fluid/pybind/eager.cc +++ b/paddle/fluid/pybind/eager.cc @@ -62,7 +62,7 @@ void EmptyTensorInitializer(TensorObject* self, const std::string& name, bool persistable = false, int stop_gradient = -1, framework::proto::VarType::Type dtype = paddle::framework::proto::VarType::FP32, - const std::vector& dims = {}, + const std::vector& dims = {0}, framework::proto::VarType::Type var_type = paddle::framework::proto::VarType::LOD_TENSOR) { auto ddims = phi::make_ddim(dims); @@ -75,7 +75,7 @@ void EmptyTensorInitializer(TensorObject* self, const std::string& name, if (var_type == paddle::framework::proto::VarType::LOD_TENSOR) { // TODO(jiabin): Maybe support LOD later std::shared_ptr dense_tensor = nullptr; - if (dims.empty()) { + if (dims.size() == 1 && dims[0] == 0) { std::shared_ptr allocation_ptr = nullptr; dense_tensor = std::make_shared( allocation_ptr, diff --git a/paddle/fluid/pybind/eager_method.cc b/paddle/fluid/pybind/eager_method.cc index 17908e80de4..ca757fac9a6 100644 --- a/paddle/fluid/pybind/eager_method.cc +++ b/paddle/fluid/pybind/eager_method.cc @@ -195,6 +195,17 @@ static PyObject* tensor_method_numpy(TensorObject* self, PyObject* args, nullptr); if (!self->tensor.impl()->initialized()) { + if (tensor_dims.size() == 0) { + py_dims[0] = 0; + py_strides[0] = 0; + PyObject* array = api.PyArray_NewFromDescr_( + api.PyArray_Type_, api.PyArray_DescrFromType_(numpy_dtype), 1, + py_dims, py_strides, nullptr, + pybind11::detail::npy_api::NPY_ARRAY_ALIGNED_ | + pybind11::detail::npy_api::NPY_ARRAY_WRITEABLE_, + nullptr); + return array; + } return array; } diff --git a/paddle/phi/api/lib/tensor.cc b/paddle/phi/api/lib/tensor.cc index 67c1b711fc9..f1aa48a2a4d 100644 --- a/paddle/phi/api/lib/tensor.cc +++ b/paddle/phi/api/lib/tensor.cc @@ -114,9 +114,6 @@ phi::DDim Tensor::dims() const { return impl_->dims(); } std::vector Tensor::shape() const { auto dims = impl_->dims(); - if (dims.size() == 1 && dims.at(0) == 0) { - return {}; - } return phi::vectorize(dims); } diff --git a/python/paddle/fluid/tests/unittests/test_egr_python_api.py b/python/paddle/fluid/tests/unittests/test_egr_python_api.py index 7e78b223b3f..600a49b2332 100644 --- a/python/paddle/fluid/tests/unittests/test_egr_python_api.py +++ b/python/paddle/fluid/tests/unittests/test_egr_python_api.py @@ -114,7 +114,7 @@ class EagerVariablePropertiesAndMethodsTestCase(unittest.TestCase): egr_tensor = core.eager.Tensor() self.assertEqual(egr_tensor.persistable, False) self.assertTrue("generated" in egr_tensor.name) - self.assertEqual(egr_tensor.shape, []) + self.assertEqual(egr_tensor.shape, [0]) self.assertEqual(egr_tensor.dtype, core.VarDesc.VarType.FP32) self.assertEqual(egr_tensor.stop_gradient, True) diff --git a/python/paddle/fluid/tests/unittests/test_var_base.py b/python/paddle/fluid/tests/unittests/test_var_base.py index 724a71ebe3d..2729aabf604 100644 --- a/python/paddle/fluid/tests/unittests/test_var_base.py +++ b/python/paddle/fluid/tests/unittests/test_var_base.py @@ -214,6 +214,13 @@ class TestVarBase(unittest.TestCase): self.assertEqual(x.item(), 1 + 1j) self.assertTrue(isinstance(x.item(), complex)) + # empty tensor + x = paddle.to_tensor([]) + self.assertEqual(x.shape, [0]) + expected_result = np.array([], dtype='float32') + self.assertEqual(x.numpy().shape, expected_result.shape) + self.assertTrue(np.array_equal(x.numpy(), expected_result)) + numpy_array = np.random.randn(3, 4) # covert core.LoDTensor to paddle.Tensor lod_tensor = paddle.fluid.core.LoDTensor() -- GitLab