|
|
|
|
@ -13,9 +13,11 @@
|
|
|
|
|
limitations under the License. */
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
#include <paddle/framework/tensor.h>
|
|
|
|
|
#include <pybind11/numpy.h>
|
|
|
|
|
#include <pybind11/pybind11.h>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include "paddle/framework/tensor.h"
|
|
|
|
|
#include "paddle/memory/memcpy.h"
|
|
|
|
|
#include "pybind11/numpy.h"
|
|
|
|
|
#include "pybind11/pybind11.h"
|
|
|
|
|
|
|
|
|
|
namespace py = pybind11;
|
|
|
|
|
|
|
|
|
|
@ -40,9 +42,6 @@ template <size_t I, typename... ARGS>
|
|
|
|
|
struct CastToPyBufferImpl<true, I, ARGS...> {
|
|
|
|
|
using CUR_TYPE = typename std::tuple_element<I, std::tuple<ARGS...>>::type;
|
|
|
|
|
py::buffer_info operator()(framework::Tensor &tensor) {
|
|
|
|
|
PADDLE_ENFORCE(paddle::platform::is_cpu_place(tensor.holder_->place()),
|
|
|
|
|
"Only CPU tensor can cast to numpy array");
|
|
|
|
|
|
|
|
|
|
if (std::type_index(typeid(CUR_TYPE)) == tensor.holder_->type()) {
|
|
|
|
|
auto dim_vec = framework::vectorize(tensor.dims());
|
|
|
|
|
std::vector<size_t> dims_outside;
|
|
|
|
|
@ -56,12 +55,17 @@ struct CastToPyBufferImpl<true, I, ARGS...> {
|
|
|
|
|
strides[i - 1] = sizeof(CUR_TYPE) * prod;
|
|
|
|
|
prod *= dims_outside[i - 1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
framework::Tensor dst_tensor;
|
|
|
|
|
if (paddle::platform::is_gpu_place(tensor.holder_->place())) {
|
|
|
|
|
dst_tensor.CopyFrom<CUR_TYPE>(tensor, platform::CPUPlace());
|
|
|
|
|
} else if (paddle::platform::is_cpu_place(tensor.holder_->place())) {
|
|
|
|
|
dst_tensor = tensor;
|
|
|
|
|
}
|
|
|
|
|
return py::buffer_info(
|
|
|
|
|
tensor.mutable_data<CUR_TYPE>(tensor.holder_->place()),
|
|
|
|
|
dst_tensor.mutable_data<CUR_TYPE>(dst_tensor.holder_->place()),
|
|
|
|
|
sizeof(CUR_TYPE),
|
|
|
|
|
py::format_descriptor<CUR_TYPE>::format(),
|
|
|
|
|
(size_t)framework::arity(tensor.dims()),
|
|
|
|
|
(size_t)framework::arity(dst_tensor.dims()),
|
|
|
|
|
dims_outside,
|
|
|
|
|
strides);
|
|
|
|
|
} else {
|
|
|
|
|
@ -77,9 +81,10 @@ inline py::buffer_info CastToPyBuffer(framework::Tensor &tensor) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
void PyTensorSetFromArray(
|
|
|
|
|
void PyCPUTensorSetFromArray(
|
|
|
|
|
framework::Tensor &self,
|
|
|
|
|
py::array_t<T, py::array::c_style | py::array::forcecast> array) {
|
|
|
|
|
py::array_t<T, py::array::c_style | py::array::forcecast> array,
|
|
|
|
|
paddle::platform::CPUPlace &place) {
|
|
|
|
|
std::vector<int> dims;
|
|
|
|
|
dims.reserve(array.ndim());
|
|
|
|
|
for (size_t i = 0; i < array.ndim(); ++i) {
|
|
|
|
|
@ -87,9 +92,28 @@ void PyTensorSetFromArray(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self.Resize(framework::make_ddim(dims));
|
|
|
|
|
auto *dst = self.mutable_data<T>(paddle::platform::CPUPlace());
|
|
|
|
|
auto *dst = self.mutable_data<T>(place);
|
|
|
|
|
std::memcpy(dst, array.data(), sizeof(T) * array.size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef PADDLE_ONLY_CPU
|
|
|
|
|
template <typename T>
|
|
|
|
|
void PyCUDATensorSetFromArray(
|
|
|
|
|
framework::Tensor &self,
|
|
|
|
|
py::array_t<T, py::array::c_style | py::array::forcecast> array,
|
|
|
|
|
paddle::platform::GPUPlace &place) {
|
|
|
|
|
std::vector<int> dims;
|
|
|
|
|
dims.reserve(array.ndim());
|
|
|
|
|
for (size_t i = 0; i < array.ndim(); ++i) {
|
|
|
|
|
dims.push_back((int)array.shape()[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self.Resize(framework::make_ddim(dims));
|
|
|
|
|
auto *dst = self.mutable_data<T>(place);
|
|
|
|
|
paddle::platform::GpuMemcpySync(
|
|
|
|
|
dst, array.data(), sizeof(T) * array.size(), cudaMemcpyHostToDevice);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
} // namespace pybind
|
|
|
|
|
} // namespace paddle
|
|
|
|
|
|