30#ifdef NUMCPP_INCLUDE_PYBIND_PYTHON_INTERFACE
32#include "pybind11/numpy.h"
33#include "pybind11/pybind11.h"
43namespace nc::pybindInterface
46 enum class ReturnPolicy
53 static const std::map<ReturnPolicy, std::string> returnPolicyStringMap = { { ReturnPolicy::COPY,
"COPY" },
54 { ReturnPolicy::REFERENCE,
"REFERENCE" },
55 { ReturnPolicy::TAKE_OWNERSHIP,
58 template<
typename dtype>
59 using pbArray = pybind11::array_t<dtype, pybind11::array::c_style>;
60 using pbArrayGeneric = pybind11::array;
70 template<
typename dtype>
71 NdArray<dtype> pybind2nc(pbArray<dtype>& numpyArray)
73 const auto dataPtr = numpyArray.mutable_data();
74 switch (numpyArray.ndim())
82 const auto size =
static_cast<uint32>(numpyArray.size());
87 const auto numRows =
static_cast<uint32>(numpyArray.shape(0));
88 const auto numCols =
static_cast<uint32>(numpyArray.shape(1));
107 template<
typename dtype>
108 NdArray<dtype> pybind2nc_copy(
const pbArray<dtype>& numpyArray)
110 const auto dataPtr = numpyArray.data();
111 switch (numpyArray.ndim())
115 return NdArray<dtype>(dataPtr, 0, 0);
119 const auto size =
static_cast<uint32>(numpyArray.size());
120 return NdArray<dtype>(dataPtr, 1,
size);
124 const auto numRows =
static_cast<uint32>(numpyArray.shape(0));
125 const auto numCols =
static_cast<uint32>(numpyArray.shape(1));
126 return NdArray<dtype>(dataPtr, numRows, numCols);
143 template<
typename dtype>
144 pbArrayGeneric nc2pybind(
const NdArray<dtype>& inArray)
146 const Shape inShape = inArray.shape();
147 const std::vector<pybind11::ssize_t>
shape{
static_cast<pybind11::ssize_t
>(inShape.rows),
148 static_cast<pybind11::ssize_t
>(inShape.cols) };
149 const std::vector<pybind11::ssize_t> strides{
static_cast<pybind11::ssize_t
>(inShape.cols *
sizeof(dtype)),
150 static_cast<pybind11::ssize_t
>(
sizeof(dtype)) };
151 return pbArrayGeneric(
shape, strides, inArray.data());
162 template<
typename dtype>
163 pbArrayGeneric nc2pybind(NdArray<dtype>& inArray, ReturnPolicy returnPolicy)
165 const Shape inShape = inArray.shape();
166 const std::vector<pybind11::ssize_t>
shape{
static_cast<pybind11::ssize_t
>(inShape.rows),
167 static_cast<pybind11::ssize_t
>(inShape.cols) };
168 const std::vector<pybind11::ssize_t> strides{
static_cast<pybind11::ssize_t
>(inShape.cols *
sizeof(dtype)),
169 static_cast<pybind11::ssize_t
>(
sizeof(dtype)) };
171 switch (returnPolicy)
173 case ReturnPolicy::COPY:
175 return nc2pybind(inArray);
177 case ReturnPolicy::REFERENCE:
179 typename pybind11::capsule reference(inArray.data(), [](
void* ) {});
180 return pbArrayGeneric(
shape, strides, inArray.data(), reference);
182 case ReturnPolicy::TAKE_OWNERSHIP:
184 typename pybind11::capsule garbageCollect(inArray.dataRelease(),
187 auto* dataPtr = reinterpret_cast<dtype*>(ptr);
190 return pbArrayGeneric(
shape, strides, inArray.data(), garbageCollect);
194 std::stringstream sstream;
195 sstream <<
"ReturnPolicy " << returnPolicyStringMap.at(returnPolicy) <<
" has not been implemented yet"
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:37
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