NumCpp  2.3.1
A Templatized Header Only C++ Implementation of the Python NumPy Library
PybindInterface.hpp
Go to the documentation of this file.
1 #pragma once
29 
30 #ifdef INCLUDE_PYBIND_PYTHON_INTERFACE
31 
33 #include "NumCpp/Core/Shape.hpp"
34 #include "NumCpp/NdArray.hpp"
35 
36 #include "pybind11/pybind11.h"
37 #include "pybind11/numpy.h"
38 
39 #include <map>
40 #include <utility>
41 
42 namespace nc
43 {
44  namespace pybindInterface
45  {
48 
49  static const std::map<ReturnPolicy, std::string> returnPolicyStringMap = { {ReturnPolicy::COPY, "COPY"},
50  {ReturnPolicy::REFERENCE, "REFERENCE"},
51  {ReturnPolicy::TAKE_OWNERSHIP, "TAKE_OWNERSHIP"} };
52 
53  //============================================================================
61  template<typename dtype>
62  inline NdArray<dtype> pybind2nc(pybind11::array_t<dtype, pybind11::array::c_style>& numpyArray)
63  {
64  dtype* dataPtr = numpyArray.mutable_data();
65  switch (numpyArray.ndim())
66  {
67  case 0:
68  {
69  return NdArray<dtype>(dataPtr, 0, 0, false);
70  }
71  case 1:
72  {
73  uint32 size = static_cast<uint32>(numpyArray.size());
74  return NdArray<dtype>(dataPtr, 1, size, false);
75  }
76  case 2:
77  {
78  uint32 numRows = static_cast<uint32>(numpyArray.shape(0));
79  uint32 numCols = static_cast<uint32>(numpyArray.shape(1));
80  return NdArray<dtype>(dataPtr, numRows, numCols, false);
81  }
82  default:
83  {
84  THROW_INVALID_ARGUMENT_ERROR("input array must be no more than 2 dimensional.");
85  return {};
86  }
87  }
88  }
89 
90  //============================================================================
98  template<typename dtype>
99  inline pybind11::array_t<dtype> nc2pybind(NdArray<dtype>& inArray, ReturnPolicy returnPolicy = ReturnPolicy::COPY)
100  {
101  Shape inShape = inArray.shape();
102  std::vector<pybind11::ssize_t> shape{ inShape.rows, inShape.cols };
103  std::vector<pybind11::ssize_t> strides{ inShape.cols * sizeof(dtype), sizeof(dtype) };
104 
105  switch (returnPolicy)
106  {
107  case ReturnPolicy::COPY:
108  {
109  return pybind11::array_t<dtype>(shape, strides, inArray.data());
110  }
112  {
113  typename pybind11::capsule reference(inArray.data(), [](void* ptr) {});
114  return pybind11::array_t<dtype>(shape, strides, inArray.data(), reference);
115  }
117  {
118  typename pybind11::capsule garbageCollect(inArray.dataRelease(),
119  [](void* ptr)
120  {
121  dtype* dataPtr = reinterpret_cast<dtype*>(ptr);
122  delete[] dataPtr;
123  }
124  );
125  return pybind11::array_t<dtype>(shape, strides, inArray.data(), garbageCollect);
126  }
127  default:
128  {
129  std::stringstream sstream;
130  sstream << "ReturnPolicy " << returnPolicyStringMap.at(returnPolicy) << " has not been implemented yet" << std::endl;
131  THROW_INVALID_ARGUMENT_ERROR(sstream.str());
132  }
133  }
134  }
135  }
136 }
137 #endif
nc::NdArray::shape
Shape shape() const noexcept
Definition: NdArrayCore.hpp:4311
nc::size
uint32 size(const NdArray< dtype > &inArray) noexcept
Definition: size.hpp:45
Error.hpp
nc::shape
Shape shape(const NdArray< dtype > &inArray) noexcept
Definition: Functions/Shape.hpp:44
nc::NdArray< dtype >
nc::uint32
std::uint32_t uint32
Definition: Types.hpp:40
NdArray.hpp
nc::pybindInterface::ReturnPolicy
ReturnPolicy
Enum for the pybind array return policy.
Definition: PybindInterface.hpp:47
nc::pybindInterface::ReturnPolicy::COPY
@ COPY
nc::NdArray::dataRelease
pointer dataRelease() noexcept
Definition: NdArrayCore.hpp:2556
nc::Shape
A Shape Class for NdArrays.
Definition: Core/Shape.hpp:40
nc::Shape::cols
uint32 cols
Definition: Core/Shape.hpp:45
nc::pybindInterface::returnPolicyStringMap
static const std::map< ReturnPolicy, std::string > returnPolicyStringMap
Definition: PybindInterface.hpp:49
Shape.hpp
nc
Definition: Coordinate.hpp:44
nc::NdArray::data
pointer data() noexcept
Definition: NdArrayCore.hpp:2534
nc::pybindInterface::pybind2nc
NdArray< dtype > pybind2nc(pybind11::array_t< dtype, pybind11::array::c_style > &numpyArray)
Definition: PybindInterface.hpp:62
nc::Shape::rows
uint32 rows
Definition: Core/Shape.hpp:44
THROW_INVALID_ARGUMENT_ERROR
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:36
nc::pybindInterface::nc2pybind
pybind11::array_t< dtype > nc2pybind(NdArray< dtype > &inArray, ReturnPolicy returnPolicy=ReturnPolicy::COPY)
Definition: PybindInterface.hpp:99
nc::pybindInterface::ReturnPolicy::TAKE_OWNERSHIP
@ TAKE_OWNERSHIP
nc::pybindInterface::ReturnPolicy::REFERENCE
@ REFERENCE