30 #ifdef NUMCPP_INCLUDE_PYBIND_PYTHON_INTERFACE
36 #include "pybind11/pybind11.h"
37 #include "pybind11/numpy.h"
44 namespace pybindInterface
47 enum class ReturnPolicy { COPY, REFERENCE, TAKE_OWNERSHIP };
49 static const std::map<ReturnPolicy, std::string> returnPolicyStringMap = { {ReturnPolicy::COPY,
"COPY"},
50 {ReturnPolicy::REFERENCE,
"REFERENCE"},
51 {ReturnPolicy::TAKE_OWNERSHIP,
"TAKE_OWNERSHIP"} };
53 template<
typename dtype>
54 using pbArray = pybind11::array_t<dtype, pybind11::array::c_style>;
55 using pbArrayGeneric = pybind11::array;
65 template<
typename dtype>
66 NdArray<dtype> pybind2nc(pbArray<dtype>& numpyArray)
68 const auto dataPtr = numpyArray.mutable_data();
69 switch (numpyArray.ndim())
73 return NdArray<dtype>(dataPtr, 0, 0,
false);
78 return NdArray<dtype>(dataPtr, 1,
size,
false);
82 const uint32 numRows =
static_cast<uint32>(numpyArray.shape(0));
83 const uint32 numCols =
static_cast<uint32>(numpyArray.shape(1));
84 return NdArray<dtype>(dataPtr, numRows, numCols,
false);
102 template<
typename dtype>
103 NdArray<dtype> pybind2nc_copy(
const pbArray<dtype>& numpyArray)
105 const auto dataPtr = numpyArray.data();
106 switch (numpyArray.ndim())
110 return NdArray<dtype>(dataPtr, 0, 0);
115 return NdArray<dtype>(dataPtr, 1,
size);
119 const uint32 numRows =
static_cast<uint32>(numpyArray.shape(0));
120 const uint32 numCols =
static_cast<uint32>(numpyArray.shape(1));
121 return NdArray<dtype>(dataPtr, numRows, numCols);
138 template<
typename dtype>
139 pbArrayGeneric nc2pybind(
const NdArray<dtype>& inArray)
141 const Shape inShape = inArray.shape();
142 const std::vector<pybind11::ssize_t>
shape{
static_cast<pybind11::ssize_t
>(inShape.rows),
143 static_cast<pybind11::ssize_t
>(inShape.cols) };
144 const std::vector<pybind11::ssize_t> strides{
static_cast<pybind11::ssize_t
>(inShape.cols *
sizeof(dtype)),
145 static_cast<pybind11::ssize_t
>(
sizeof(dtype)) };
146 return pbArrayGeneric(
shape, strides, inArray.data());
157 template<
typename dtype>
158 pbArrayGeneric nc2pybind(NdArray<dtype>& inArray, ReturnPolicy returnPolicy)
160 const Shape inShape = inArray.shape();
161 const std::vector<pybind11::ssize_t>
shape{
static_cast<pybind11::ssize_t
>(inShape.rows),
162 static_cast<pybind11::ssize_t
>(inShape.cols) };
163 const std::vector<pybind11::ssize_t> strides{
static_cast<pybind11::ssize_t
>(inShape.cols *
sizeof(dtype)),
164 static_cast<pybind11::ssize_t
>(
sizeof(dtype)) };
166 switch (returnPolicy)
168 case ReturnPolicy::COPY:
170 return nc2pybind(inArray);
172 case ReturnPolicy::REFERENCE:
174 typename pybind11::capsule reference(inArray.data(), [](
void* ) {});
175 return pbArrayGeneric(
shape, strides, inArray.data(), reference);
177 case ReturnPolicy::TAKE_OWNERSHIP:
179 typename pybind11::capsule garbageCollect(inArray.dataRelease(),
182 dtype* dataPtr = reinterpret_cast<dtype*>(ptr);
186 return pbArrayGeneric(
shape, strides, inArray.data(), garbageCollect);
190 std::stringstream sstream;
191 sstream <<
"ReturnPolicy " << returnPolicyStringMap.at(returnPolicy) <<
" has not been implemented yet" << std::endl;
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:36
Definition: Coordinate.hpp:45
uint32 size(const NdArray< dtype > &inArray) noexcept
Definition: size.hpp:43
Shape shape(const NdArray< dtype > &inArray) noexcept
Definition: Functions/Shape.hpp:42
std::uint32_t uint32
Definition: Types.hpp:40