eigenpy 3.12.0
Bindings between Numpy and Eigen using Boost.Python
Loading...
Searching...
No Matches
eigen-from-python.hpp
1//
2// Copyright (c) 2023 INRIA
3//
4
5#ifndef __eigenpy_tensor_eigen_from_python_hpp__
6#define __eigenpy_tensor_eigen_from_python_hpp__
7
8#include "eigenpy/fwd.hpp"
9#include "eigenpy/eigen-allocator.hpp"
10#include "eigenpy/numpy-type.hpp"
11#include "eigenpy/scalar-conversion.hpp"
12
13namespace eigenpy {
14
15template <typename TensorType>
16struct expected_pytype_for_arg<TensorType, Eigen::TensorBase<TensorType>> {
17 static PyTypeObject const *get_pytype() {
18 PyTypeObject const *py_type = eigenpy::getPyArrayType();
19 return py_type;
20 }
21};
22
23} // namespace eigenpy
24
25namespace boost {
26namespace python {
27namespace converter {
28
29template <typename Scalar, int Rank, int Options, typename IndexType>
30struct expected_pytype_for_arg<Eigen::Tensor<Scalar, Rank, Options, IndexType>>
32 Eigen::Tensor<Scalar, Rank, Options, IndexType>> {};
33
34template <typename Scalar, int Rank, int Options, typename IndexType>
35struct rvalue_from_python_data<
36 Eigen::Tensor<Scalar, Rank, Options, IndexType> const &>
38 Eigen::Tensor<Scalar, Rank, Options, IndexType> const &> {
39 typedef Eigen::Tensor<Scalar, Rank, Options, IndexType> T;
40 EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(T const &)
41};
42
43template <typename Derived>
44struct rvalue_from_python_data<Eigen::TensorBase<Derived> const &>
45 : ::eigenpy::rvalue_from_python_data<Derived const &> {
46 EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(Derived const &)
47};
48
49} // namespace converter
50} // namespace python
51} // namespace boost
52
53namespace boost {
54namespace python {
55namespace detail {
56template <typename TensorType>
57struct referent_storage<Eigen::TensorRef<TensorType> &> {
58 typedef Eigen::TensorRef<TensorType> RefType;
59 typedef ::eigenpy::details::referent_storage_eigen_ref<RefType> StorageType;
60 typedef typename ::eigenpy::aligned_storage<
61 referent_size<StorageType &>::value>::type type;
62};
63
64template <typename TensorType>
65struct referent_storage<const Eigen::TensorRef<const TensorType> &> {
66 typedef Eigen::TensorRef<const TensorType> RefType;
67 typedef ::eigenpy::details::referent_storage_eigen_ref<RefType> StorageType;
68 typedef typename ::eigenpy::aligned_storage<
69 referent_size<StorageType &>::value>::type type;
70};
71} // namespace detail
72} // namespace python
73} // namespace boost
74
75namespace eigenpy {
76
77template <typename TensorType>
78struct eigen_from_py_impl<TensorType, Eigen::TensorBase<TensorType>> {
79 typedef typename TensorType::Scalar Scalar;
80
82 static void *convertible(PyObject *pyObj);
83
85 static void construct(PyObject *pyObj,
86 bp::converter::rvalue_from_python_stage1_data *memory);
87
88 static void registration();
89};
90
91template <typename TensorType>
92void *
94 PyObject *pyObj) {
95 if (!call_PyArray_Check(reinterpret_cast<PyObject *>(pyObj))) return 0;
96
97 typedef typename Eigen::internal::traits<TensorType>::Index Index;
98 static const Index NumIndices = TensorType::NumIndices;
99
100 PyArrayObject *pyArray = reinterpret_cast<PyArrayObject *>(pyObj);
101
102 if (!np_type_is_convertible_into_scalar<Scalar>(
103 EIGENPY_GET_PY_ARRAY_TYPE(pyArray)))
104 return 0;
105
106 if (!(PyArray_NDIM(pyArray) == NumIndices || NumIndices == Eigen::Dynamic))
107 return 0;
108
109#ifdef NPY_1_8_API_VERSION
110 if (!(PyArray_FLAGS(pyArray)))
111#else
112 if (!(PyArray_FLAGS(pyArray) & NPY_ALIGNED))
113#endif
114 {
115 return 0;
116 }
117
118 return pyArray;
119}
120
121template <typename TensorType>
123 PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory) {
124 eigen_from_py_construct<TensorType>(pyObj, memory);
125}
126
127template <typename TensorType>
128void eigen_from_py_impl<TensorType,
129 Eigen::TensorBase<TensorType>>::registration() {
130 bp::converter::registry::push_back(
131 reinterpret_cast<void *(*)(_object *)>(&eigen_from_py_impl::convertible),
132 &eigen_from_py_impl::construct, bp::type_id<TensorType>()
133#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
134 ,
136#endif
137 );
138}
139
140template <typename TensorType>
141struct eigen_from_py_converter_impl<TensorType, Eigen::TensorBase<TensorType>> {
142 static void registration() {
143 EigenFromPy<TensorType>::registration();
144
145 // Add conversion to Eigen::TensorBase<TensorType>
146 typedef Eigen::TensorBase<TensorType> TensorBase;
147 EigenFromPy<TensorBase>::registration();
148
149 // Add conversion to Eigen::TensorRef<TensorType>
150 typedef Eigen::TensorRef<TensorType> RefType;
151 EigenFromPy<RefType>::registration();
152
153 // Add conversion to Eigen::TensorRef<const TensorType>
154 typedef const Eigen::TensorRef<const TensorType> ConstRefType;
155 EigenFromPy<ConstRefType>::registration();
156 }
157};
158
159template <typename TensorType>
160struct EigenFromPy<Eigen::TensorBase<TensorType>> : EigenFromPy<TensorType> {
161 typedef EigenFromPy<TensorType> EigenFromPyDerived;
162 typedef Eigen::TensorBase<TensorType> Base;
163
164 static void registration() {
165 bp::converter::registry::push_back(
166 reinterpret_cast<void *(*)(_object *)>(&EigenFromPy::convertible),
167 &EigenFromPy::construct, bp::type_id<Base>()
168#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
169 ,
171#endif
172 );
173 }
174};
175
176template <typename TensorType>
177struct EigenFromPy<Eigen::TensorRef<TensorType>> {
178 typedef Eigen::TensorRef<TensorType> RefType;
179 typedef typename TensorType::Scalar Scalar;
180
182 static void *convertible(PyObject *pyObj) {
183 if (!call_PyArray_Check(pyObj)) return 0;
184 PyArrayObject *pyArray = reinterpret_cast<PyArrayObject *>(pyObj);
185 if (!PyArray_ISWRITEABLE(pyArray)) return 0;
187 }
188
189 static void registration() {
190 bp::converter::registry::push_back(
191 reinterpret_cast<void *(*)(_object *)>(&EigenFromPy::convertible),
192 &eigen_from_py_construct<RefType>, bp::type_id<RefType>()
193#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
194 ,
196#endif
197 );
198 }
199};
200
201template <typename TensorType>
202struct EigenFromPy<const Eigen::TensorRef<const TensorType>> {
203 typedef const Eigen::TensorRef<const TensorType> ConstRefType;
204 typedef typename TensorType::Scalar Scalar;
205
207 static void *convertible(PyObject *pyObj) {
209 }
210
211 static void registration() {
212 bp::converter::registry::push_back(
213 reinterpret_cast<void *(*)(_object *)>(&EigenFromPy::convertible),
214 &eigen_from_py_construct<ConstRefType>, bp::type_id<ConstRefType>()
215#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
216 ,
218#endif
219 );
220 }
221};
222
223} // namespace eigenpy
224
225#endif // __eigenpy_tensor_eigen_from_python_hpp__
static void * convertible(PyObject *pyObj)
Determine if pyObj can be converted into a MatType object.
static void * convertible(PyObject *pyObj)
Determine if pyObj can be converted into a MatType object.
static void construct(PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory)
Allocate memory and copy pyObj in the new storage.
static void * convertible(PyObject *pyObj)
Determine if pyObj can be converted into a MatType object.
static void construct(PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory)
Allocate memory and copy pyObj in the new storage.
static void * convertible(PyObject *pyObj)
Determine if pyObj can be converted into a MatType object.