NumCpp  2.4.0
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  template<typename dtype>
54  using pbArray = pybind11::array_t<dtype, pybind11::array::c_style>;
55  using pbArrayGeneric = pybind11::array;
56 
57  //============================================================================
65  template<typename dtype>
67  {
68  const auto dataPtr = numpyArray.mutable_data();
69  switch (numpyArray.ndim())
70  {
71  case 0:
72  {
73  return NdArray<dtype>(dataPtr, 0, 0, false);
74  }
75  case 1:
76  {
77  const uint32 size = static_cast<uint32>(numpyArray.size());
78  return NdArray<dtype>(dataPtr, 1, size, false);
79  }
80  case 2:
81  {
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);
85  }
86  default:
87  {
88  THROW_INVALID_ARGUMENT_ERROR("input array must be no more than 2 dimensional.");
89  return {};
90  }
91  }
92  }
93 
94  //============================================================================
102  template<typename dtype>
104  {
105  const auto dataPtr = numpyArray.data();
106  switch (numpyArray.ndim())
107  {
108  case 0:
109  {
110  return NdArray<dtype>(dataPtr, 0, 0);
111  }
112  case 1:
113  {
114  const uint32 size = static_cast<uint32>(numpyArray.size());
115  return NdArray<dtype>(dataPtr, 1, size);
116  }
117  case 2:
118  {
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);
122  }
123  default:
124  {
125  THROW_INVALID_ARGUMENT_ERROR("input array must be no more than 2 dimensional.");
126  return {};
127  }
128  }
129  }
130 
131  //============================================================================
138  template<typename dtype>
140  {
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());
147  }
148 
149  //============================================================================
157  template<typename dtype>
159  {
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)) };
165 
166  switch (returnPolicy)
167  {
168  case ReturnPolicy::COPY:
169  {
170  return nc2pybind(inArray);
171  }
173  {
174  typename pybind11::capsule reference(inArray.data(), [](void* /*ptr*/) {});
175  return pbArrayGeneric(shape, strides, inArray.data(), reference);
176  }
178  {
179  typename pybind11::capsule garbageCollect(inArray.dataRelease(),
180  [](void* ptr)
181  {
182  dtype* dataPtr = reinterpret_cast<dtype*>(ptr);
183  delete[] dataPtr;
184  }
185  );
186  return pbArrayGeneric(shape, strides, inArray.data(), garbageCollect);
187  }
188  default:
189  {
190  std::stringstream sstream;
191  sstream << "ReturnPolicy " << returnPolicyStringMap.at(returnPolicy) << " has not been implemented yet" << std::endl;
192  THROW_INVALID_ARGUMENT_ERROR(sstream.str());
193  }
194  }
195  }
196  }
197 }
198 #endif
nc::NdArray::shape
Shape shape() const noexcept
Definition: NdArrayCore.hpp:4356
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:2574
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:2552
nc::Shape::rows
uint32 rows
Definition: Core/Shape.hpp:44
nc::pybindInterface::nc2pybind
pbArrayGeneric nc2pybind(const NdArray< dtype > &inArray)
Definition: PybindInterface.hpp:139
THROW_INVALID_ARGUMENT_ERROR
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:36
nc::pybindInterface::pybind2nc_copy
NdArray< dtype > pybind2nc_copy(const pbArray< dtype > &numpyArray)
Definition: PybindInterface.hpp:103
nc::pybindInterface::ReturnPolicy::TAKE_OWNERSHIP
@ TAKE_OWNERSHIP
nc::pybindInterface::pbArray
pybind11::array_t< dtype, pybind11::array::c_style > pbArray
Definition: PybindInterface.hpp:54
nc::pybindInterface::pbArrayGeneric
pybind11::array pbArrayGeneric
Definition: PybindInterface.hpp:55
nc::pybindInterface::pybind2nc
NdArray< dtype > pybind2nc(pbArray< dtype > &numpyArray)
Definition: PybindInterface.hpp:66
nc::pybindInterface::ReturnPolicy::REFERENCE
@ REFERENCE