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 bool Register::isRegistered(PyTypeObject* py_type_ptr) {
18  if (getPyArrayDescr(py_type_ptr) != NULL)
19  return true;
20  else
21  return false;
22 }
23 
24 int Register::getTypeCode(PyTypeObject* py_type_ptr) {
25  MapCode::iterator it = instance().py_array_code_bindings.find(py_type_ptr);
26  if (it != instance().py_array_code_bindings.end())
27  return it->second;
28  else
29  return PyArray_TypeNum(py_type_ptr);
30 }
31 
33  PyTypeObject* py_type_ptr, const std::type_info* type_info_ptr,
34  const int type_size, const int alignement, PyArray_GetItemFunc* getitem,
35  PyArray_SetItemFunc* setitem, PyArray_NonzeroFunc* nonzero,
36  PyArray_CopySwapFunc* copyswap, PyArray_CopySwapNFunc* copyswapn,
37  PyArray_DotFunc* dotfunc, PyArray_FillFunc* fill,
38  PyArray_FillWithScalarFunc* fillwithscalar) {
39  bp::tuple tp_bases_extended(
40  bp::make_tuple(bp::handle<>(bp::borrowed(&PyGenericArrType_Type))));
41  tp_bases_extended +=
42  bp::tuple(bp::handle<>(bp::borrowed(py_type_ptr->tp_bases)));
43 
44  Py_INCREF(tp_bases_extended.ptr());
45  py_type_ptr->tp_bases = tp_bases_extended.ptr();
46 
47  py_type_ptr->tp_flags &= ~Py_TPFLAGS_READY; // to force the rebuild
48  // py_type_ptr->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE;
49  if (PyType_Ready(py_type_ptr) <
50  0) // Force rebuilding of the __bases__ and mro
51  {
52  throw std::invalid_argument("PyType_Ready fails to initialize input type.");
53  }
54 
55  PyArray_Descr* descr_ptr =
56  new PyArray_Descr(*call_PyArray_DescrFromType(NPY_OBJECT));
57  PyArray_Descr& descr = *descr_ptr;
58  descr.typeobj = py_type_ptr;
59  descr.kind = 'V';
60  descr.byteorder = '=';
61  descr.type = 'r';
62  descr.elsize = type_size;
63  descr.flags =
64  NPY_NEEDS_PYAPI | NPY_USE_GETITEM | NPY_USE_SETITEM | NPY_NEEDS_INIT;
65  descr.type_num = 0;
66  descr.names = 0;
67  descr.fields = 0;
68  descr.alignment =
69  alignement; // call_PyArray_DescrFromType(NPY_OBJECT)->alignment;
70 
71  PyArray_ArrFuncs* funcs_ptr = new PyArray_ArrFuncs;
72  PyArray_ArrFuncs& funcs = *funcs_ptr;
73  descr.f = funcs_ptr;
74  call_PyArray_InitArrFuncs(funcs_ptr);
75  funcs.getitem = getitem;
76  funcs.setitem = setitem;
77  funcs.nonzero = nonzero;
78  funcs.copyswap = copyswap;
79  funcs.copyswapn = copyswapn;
80  funcs.dotfunc = dotfunc;
81  funcs.fill = fill;
82  funcs.fillwithscalar = fillwithscalar;
83  // f->cast = cast;
84 
85  const int code = call_PyArray_RegisterDataType(descr_ptr);
86  assert(code >= 0 && "The return code should be positive");
87  PyArray_Descr* new_descr = call_PyArray_DescrFromType(code);
88 
89  if (PyDict_SetItemString(py_type_ptr->tp_dict, "dtype",
90  (PyObject*)descr_ptr) < 0) {
91  throw std::invalid_argument("PyDict_SetItemString fails.");
92  }
93 
95  std::make_pair(type_info_ptr, py_type_ptr));
96  instance().py_array_descr_bindings[py_type_ptr] = new_descr;
97  instance().py_array_code_bindings[py_type_ptr] = code;
98 
99  // PyArray_RegisterCanCast(descr,NPY_OBJECT,NPY_NOSCALAR);
100  return code;
101 }
102 
104  static Register self;
105  return self;
106 }
107 
108 } // 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:169
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:103
eigenpy::call_PyArray_DescrFromType
PyArray_Descr * call_PyArray_DescrFromType(int typenum)
Definition: numpy.hpp:165
eigenpy::Register::isRegistered
static bool isRegistered()
Definition: register.hpp:24
eigenpy::Register::type_to_py_type_bindings
MapInfo type_to_py_type_bindings
Definition: register.hpp:106
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:32
eigenpy
Definition: alignment.hpp:14
eigenpy::Register::getPyArrayDescr
static PyArray_Descr * getPyArrayDescr()
Definition: register.hpp:54
eigenpy::Register::getTypeCode
static int getTypeCode()
Definition: register.hpp:63
eigenpy::Register::py_array_code_bindings
MapCode py_array_code_bindings
Definition: register.hpp:113
eigenpy::call_PyArray_RegisterDataType
int call_PyArray_RegisterDataType(PyArray_Descr *dtype)
Definition: numpy.hpp:173
eigenpy::Register::py_array_descr_bindings
MapDescr py_array_descr_bindings
Definition: register.hpp:110


eigenpy
Author(s): Justin Carpentier, Nicolas Mansard
autogenerated on Tue Jan 23 2024 03:15:01