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