diff --git a/paddle/fluid/pybind/tensor_py.h b/paddle/fluid/pybind/tensor_py.h index 2aae3e0f8374b8214044e6b9d9f59de69553a9b0..a6078088944be4488a9cfb4a77a9bc9326a69f71 100644 --- a/paddle/fluid/pybind/tensor_py.h +++ b/paddle/fluid/pybind/tensor_py.h @@ -140,7 +140,8 @@ void TensorSetElement(framework::Tensor *self, size_t offset, T elem) { template void SetTensorFromPyArrayT( framework::Tensor *self, - py::array_t array, P place) { + const py::array_t &array, + const P &place) { std::vector dims; dims.reserve(array.ndim()); for (decltype(array.ndim()) i = 0; i < array.ndim(); ++i) { @@ -171,8 +172,9 @@ void SetTensorFromPyArrayT( } template -void SetTensorFromPyArray(framework::Tensor *self, pybind11::array array, - P place) { +void SetTensorFromPyArray(framework::Tensor *self, const py::object &obj, + const P &place) { + auto array = obj.cast(); if (py::isinstance>(array)) { SetTensorFromPyArrayT(self, array, place); } else if (py::isinstance>(array)) { @@ -202,42 +204,6 @@ void SetTensorFromPyArray(framework::Tensor *self, pybind11::array array, } } -template -void PyCPUTensorSetFromArray( - framework::Tensor *self, - pybind11::array_t - array, - paddle::platform::CPUPlace place) { - std::vector dims; - dims.reserve(array.ndim()); - for (decltype(array.ndim()) i = 0; i < array.ndim(); ++i) { - dims.push_back(static_cast(array.shape()[i])); - } - - self->Resize(framework::make_ddim(dims)); - auto *dst = self->mutable_data(place); - std::memcpy(dst, array.data(), sizeof(T) * array.size()); -} - -template <> -// This following specialization maps uint16_t in the parameter type to -// platform::float16. -inline void PyCPUTensorSetFromArray( - framework::Tensor *self, - pybind11::array_t - array, - paddle::platform::CPUPlace place) { - std::vector dims; - dims.reserve(array.ndim()); - for (decltype(array.ndim()) i = 0; i < array.ndim(); ++i) { - dims.push_back(static_cast(array.shape()[i])); - } - self->Resize(framework::make_ddim(dims)); - auto *dst = self->mutable_data(place); - std::memcpy(dst, array.data(), sizeof(uint16_t) * array.size()); -} - template void _sliceCompute(const framework::Tensor *in, framework::Tensor *out, const platform::CPUDeviceContext &ctx, @@ -485,84 +451,6 @@ inline framework::Tensor *PySliceTensor(const framework::Tensor &self, } } -#ifdef PADDLE_WITH_CUDA -template -void PyCUDATensorSetFromArray( - framework::Tensor *self, - pybind11::array_t - array, - paddle::platform::CUDAPlace place) { - std::vector dims; - dims.reserve(array.ndim()); - for (decltype(array.ndim()) i = 0; i < array.ndim(); ++i) { - dims.push_back(static_cast(array.shape()[i])); - } - self->Resize(framework::make_ddim(dims)); - auto *dst = self->mutable_data(place); - paddle::platform::GpuMemcpySync(dst, array.data(), sizeof(T) * array.size(), - cudaMemcpyHostToDevice); -} - -template <> -// This following specialization maps uint16_t in the parameter type to -// platform::float16. -inline void PyCUDATensorSetFromArray( - framework::Tensor *self, - pybind11::array_t - array, - paddle::platform::CUDAPlace place) { - std::vector dims; - dims.reserve(array.ndim()); - for (decltype(array.ndim()) i = 0; i < array.ndim(); ++i) { - dims.push_back(static_cast(array.shape()[i])); - } - - self->Resize(framework::make_ddim(dims)); - auto *dst = self->mutable_data(place); - paddle::platform::GpuMemcpySync(dst, array.data(), - sizeof(uint16_t) * array.size(), - cudaMemcpyHostToDevice); -} - -template -void PyCUDAPinnedTensorSetFromArray( - framework::Tensor *self, - pybind11::array_t - array, - const paddle::platform::CUDAPinnedPlace &place) { - std::vector dims; - dims.reserve(array.ndim()); - for (decltype(array.ndim()) i = 0; i < array.ndim(); ++i) { - dims.push_back(static_cast(array.shape()[i])); - } - - self->Resize(framework::make_ddim(dims)); - auto *dst = self->mutable_data(place); - std::memcpy(dst, array.data(), sizeof(T) * array.size()); -} - -template <> -// This following specialization maps uint16_t in the parameter type to -// platform::float16. -inline void PyCUDAPinnedTensorSetFromArray( - framework::Tensor *self, - pybind11::array_t - array, - const paddle::platform::CUDAPinnedPlace &place) { - std::vector dims; - dims.reserve(array.ndim()); - for (decltype(array.ndim()) i = 0; i < array.ndim(); ++i) { - dims.push_back(static_cast(array.shape()[i])); - } - - self->Resize(framework::make_ddim(dims)); - auto *dst = self->mutable_data(place); - std::memcpy(dst, array.data(), sizeof(uint16_t) * array.size()); -} -#endif - inline py::array TensorToPyArray(const framework::Tensor &tensor) { if (!tensor.IsInitialized()) { return py::array(); diff --git a/python/paddle/fluid/tests/unittests/test_tensor.py b/python/paddle/fluid/tests/unittests/test_tensor.py index 09417a3e1e0752ca2104fb5032ade2b634c863c2..71dd49504a58ee290351e81fed0355e192059daf 100644 --- a/python/paddle/fluid/tests/unittests/test_tensor.py +++ b/python/paddle/fluid/tests/unittests/test_tensor.py @@ -280,6 +280,45 @@ class TestTensor(unittest.TestCase): isinstance( tensor._mutable_data(places[0], dtype), numbers.Integral)) + def test_tensor_set_fp16(self): + array = numpy.random.random((300, 500)).astype("float16") + tensor = fluid.Tensor() + place = core.CPUPlace() + tensor.set(array, place) + self.assertEqual(tensor._dtype(), core.VarDesc.VarType.FP16) + self.assertTrue(numpy.array_equal(numpy.array(tensor), array)) + + if core.is_compiled_with_cuda(): + place = core.CUDAPlace(0) + tensor.set(array, place) + self.assertEqual(tensor._dtype(), core.VarDesc.VarType.FP16) + self.assertTrue(numpy.array_equal(numpy.array(tensor), array)) + + place = core.CUDAPinnedPlace() + tensor.set(array, place) + self.assertEqual(tensor._dtype(), core.VarDesc.VarType.FP16) + self.assertTrue(numpy.array_equal(numpy.array(tensor), array)) + + def test_tensor_set_from_array_list(self): + array = numpy.random.randint(1000, size=(200, 300)) + list_array = [array, array] + tensor = fluid.Tensor() + place = core.CPUPlace() + tensor.set(list_array, place) + self.assertEqual([2, 200, 300], tensor.shape()) + self.assertTrue(numpy.array_equal(numpy.array(tensor), list_array)) + + if core.is_compiled_with_cuda(): + place = core.CUDAPlace(0) + tensor.set(list_array, place) + self.assertEqual([2, 200, 300], tensor.shape()) + self.assertTrue(numpy.array_equal(numpy.array(tensor), list_array)) + + place = core.CUDAPinnedPlace() + tensor.set(list_array, place) + self.assertEqual([2, 200, 300], tensor.shape()) + self.assertTrue(numpy.array_equal(numpy.array(tensor), list_array)) + if __name__ == '__main__': unittest.main()