register.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020-2021 INRIA
3  */
4 
5 #include "eigenpy/register.hpp"
6 
7 namespace eigenpy {
8 
9 PyArray_Descr* Register::getPyArrayDescr(PyTypeObject* py_type_ptr) {
10  MapDescr::iterator it = instance().py_array_descr_bindings.find(py_type_ptr);
11  if (it != instance().py_array_descr_bindings.end())
12  return it->second;
13  else
14  return NULL;
15 }
16 
17 PyArray_Descr* Register::getPyArrayDescrFromTypeNum(const int type_num) {
18  if (type_num >= NPY_USERDEF) {
19  for (const auto& elt : instance().py_array_code_bindings) {
20  if (elt.second == type_num)
21  return instance().py_array_descr_bindings[elt.first];
22  }
23  return nullptr;
24  } else
25  return PyArray_DescrFromType(type_num);
26 }
27 
28 bool Register::isRegistered(PyTypeObject* py_type_ptr) {
29  if (getPyArrayDescr(py_type_ptr) != NULL)
30  return true;
31  else
32  return false;
33 }
34 
35 int Register::getTypeCode(PyTypeObject* py_type_ptr) {
36  MapCode::iterator it = instance().py_array_code_bindings.find(py_type_ptr);
37  if (it != instance().py_array_code_bindings.end())
38  return it->second;
39  else
40  return PyArray_TypeNum(py_type_ptr);
41 }
42 
44  PyTypeObject* py_type_ptr, const std::type_info* type_info_ptr,
45  const int type_size, const int alignement, PyArray_GetItemFunc* getitem,
46  PyArray_SetItemFunc* setitem, PyArray_NonzeroFunc* nonzero,
47  PyArray_CopySwapFunc* copyswap, PyArray_CopySwapNFunc* copyswapn,
48  PyArray_DotFunc* dotfunc, PyArray_FillFunc* fill,
49  PyArray_FillWithScalarFunc* fillwithscalar) {
50  bp::tuple tp_bases_extended(
51  bp::make_tuple(bp::handle<>(bp::borrowed(&PyGenericArrType_Type))));
52  tp_bases_extended +=
53  bp::tuple(bp::handle<>(bp::borrowed(py_type_ptr->tp_bases)));
54 
55  Py_INCREF(tp_bases_extended.ptr());
56  py_type_ptr->tp_bases = tp_bases_extended.ptr();
57 
58  py_type_ptr->tp_flags &= ~Py_TPFLAGS_READY; // to force the rebuild
59  // py_type_ptr->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE;
60  if (PyType_Ready(py_type_ptr) <
61  0) // Force rebuilding of the __bases__ and mro
62  {
63  throw std::invalid_argument("PyType_Ready fails to initialize input type.");
64  }
65 
66  PyArray_DescrProto* descr_ptr = new PyArray_DescrProto();
67  Py_SET_TYPE(descr_ptr, &PyArrayDescr_Type);
68  PyArray_DescrProto& descr = *descr_ptr;
69  descr.typeobj = py_type_ptr;
70  descr.kind = 'V';
71  descr.byteorder = '=';
72  descr.type = 'r';
73  descr.elsize = type_size;
74  descr.flags =
75  NPY_NEEDS_PYAPI | NPY_USE_GETITEM | NPY_USE_SETITEM | NPY_NEEDS_INIT;
76  descr.type_num = 0;
77  descr.names = 0;
78  descr.fields = 0;
79  descr.alignment =
80  alignement; // call_PyArray_DescrFromType(NPY_OBJECT)->alignment;
81 
82  PyArray_ArrFuncs* funcs_ptr = new PyArray_ArrFuncs;
83  PyArray_ArrFuncs& funcs = *funcs_ptr;
84  descr.f = funcs_ptr;
85  call_PyArray_InitArrFuncs(funcs_ptr);
86  funcs.getitem = getitem;
87  funcs.setitem = setitem;
88  funcs.nonzero = nonzero;
89  funcs.copyswap = copyswap;
90  funcs.copyswapn = copyswapn;
91  funcs.dotfunc = dotfunc;
92  funcs.fill = fill;
93  funcs.fillwithscalar = fillwithscalar;
94  // f->cast = cast;
95 
96  const int code = call_PyArray_RegisterDataType(descr_ptr);
97  assert(code >= 0 && "The return code should be positive");
98  PyArray_Descr* new_descr = call_PyArray_DescrFromType(code);
99 
100  if (PyDict_SetItemString(py_type_ptr->tp_dict, "dtype",
101  (PyObject*)new_descr) < 0) {
102  throw std::invalid_argument("PyDict_SetItemString fails.");
103  }
104 
106  std::make_pair(type_info_ptr, py_type_ptr));
107  instance().py_array_descr_bindings[py_type_ptr] = new_descr;
108  instance().py_array_code_bindings[py_type_ptr] = code;
109 
110  // PyArray_RegisterCanCast(descr,NPY_OBJECT,NPY_NOSCALAR);
111  return code;
112 }
113 
115  static Register self;
116  return self;
117 }
118 
119 } // namespace eigenpy
eigenpy::PyArray_TypeNum
int EIGENPY_DLLAPI PyArray_TypeNum(PyTypeObject *type)
Definition: numpy.cpp:16
eigenpy::call_PyArray_InitArrFuncs
void call_PyArray_InitArrFuncs(PyArray_ArrFuncs *funcs)
Definition: numpy.hpp:270
register.hpp
fill
void fill(Eigen::Ref< MatType > mat, const typename MatType::Scalar &value)
Definition: eigen_ref.cpp:62
eigenpy::Register::instance
static Register & instance()
Definition: register.cpp:114
eigenpy::call_PyArray_DescrFromType
PyArray_Descr * call_PyArray_DescrFromType(int typenum)
Definition: numpy.hpp:266
eigenpy::Register::getPyArrayDescrFromTypeNum
static PyArray_Descr * getPyArrayDescrFromTypeNum(const int type_num)
Definition: register.cpp:17
eigenpy::call_PyArray_RegisterDataType
int call_PyArray_RegisterDataType(PyArray_DescrProto *dtype)
Definition: numpy.hpp:274
eigenpy::Register::isRegistered
static bool isRegistered()
Definition: register.hpp:43
eigenpy::Register::type_to_py_type_bindings
MapInfo type_to_py_type_bindings
Definition: register.hpp:125
eigenpy::Register
Structure collecting all the types registers in Numpy via EigenPy.
Definition: register.hpp:20
eigenpy::Register::registerNewType
static int registerNewType(PyTypeObject *py_type_ptr, const std::type_info *type_info_ptr, const int type_size, const int alignment, PyArray_GetItemFunc *getitem, PyArray_SetItemFunc *setitem, PyArray_NonzeroFunc *nonzero, PyArray_CopySwapFunc *copyswap, PyArray_CopySwapNFunc *copyswapn, PyArray_DotFunc *dotfunc, PyArray_FillFunc *fill, PyArray_FillWithScalarFunc *fillwithscalar)
Definition: register.cpp:43
eigenpy
Definition: alignment.hpp:14
eigenpy::type_info
boost::typeindex::type_index type_info(const T &value)
Definition: type_info.hpp:17
eigenpy::Register::getPyArrayDescr
static PyArray_Descr * getPyArrayDescr()
Definition: register.hpp:73
eigenpy::Register::getTypeCode
static int getTypeCode()
Definition: register.hpp:82
Py_SET_TYPE
#define Py_SET_TYPE(o, type)
Definition: numpy.hpp:48
eigenpy::Register::py_array_code_bindings
MapCode py_array_code_bindings
Definition: register.hpp:132
PyArray_DescrProto
#define PyArray_DescrProto
Definition: numpy.hpp:29
eigenpy::Register::py_array_descr_bindings
MapDescr py_array_descr_bindings
Definition: register.hpp:129


eigenpy
Author(s): Justin Carpentier, Nicolas Mansard
autogenerated on Sat Nov 2 2024 02:14:45