1 #ifndef CONVERTER_IMPL_HXX
2 #define CONVERTER_IMPL_HXX
4 #include <boost/python/detail/wrap_python.hpp>
5 #include <boost/python.hpp>
9 #include <numpy/arrayobject.h>
11 #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
17 #include <boost/python.hpp>
18 #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
31 PyErr_SetString(PyExc_ValueError,
"no mapping available for this type");
32 boost::python::throw_error_already_set();
42 template <>
inline NPY_TYPES typeEnumFromType<opengm::UInt8Type>(void) {
46 template <>
inline NPY_TYPES typeEnumFromType<opengm::UInt16Type>(void) {
50 template <>
inline NPY_TYPES typeEnumFromType<opengm::UInt32Type>(void) {
54 template <>
inline NPY_TYPES typeEnumFromType<opengm::UInt64Type>(void) {
58 template <>
inline NPY_TYPES typeEnumFromType<opengm::Int8Type>(void) {
62 template <>
inline NPY_TYPES typeEnumFromType<opengm::Int16Type>(void) {
66 template <>
inline NPY_TYPES typeEnumFromType<opengm::Int32Type>(void) {
70 template <>
inline NPY_TYPES typeEnumFromType<opengm::Int64Type>(void) {
85 template<
class VALUE_TYPE>
86 inline boost::python::object
get1dArray(
const size_t size){
87 npy_intp dims[1]={
static_cast<int>(size)};
88 boost::python::object obj(boost::python::handle<>(PyArray_SimpleNew(
int(1), dims, typeEnumFromType<VALUE_TYPE>() )));
92 template<
class VALUE_TYPE>
93 inline boost::python::object
get2dArray(
const size_t size1,
const size_t size2){
94 npy_intp dims[2]={
static_cast<int>(size1),static_cast<int>(size2)};
95 boost::python::object obj(boost::python::handle<>(PyArray_SimpleNew(
int(2), dims, typeEnumFromType<VALUE_TYPE>() )));
100 template<
class VALUE_TYPE,
class FORWARD_SHAPE_ITERATOR>
101 inline boost::python::object
getArray(FORWARD_SHAPE_ITERATOR begin,FORWARD_SHAPE_ITERATOR end){
102 const int nDim=std::distance(begin,end);
103 npy_intp * dims =
new npy_intp[nDim];
104 std::copy(begin,end,dims);
105 boost::python::object obj(boost::python::handle<>(PyArray_SimpleNew(nDim, dims, typeEnumFromType<VALUE_TYPE>() )));
110 template<
class VALUE_TYPE>
112 void *array_data = PyArray_DATA((PyArrayObject*) obj.ptr());
113 return static_cast< VALUE_TYPE *
>(array_data);
116 inline boost::python::numeric::array
objToArray(boost::python::object obj){
117 return boost::python::extract<boost::python::numeric::array > (obj);
124 if (value == PyArray_UBYTE)
return std::string(
"PyArray_UBYTE");
125 else if (value == PyArray_BOOL)
return std::string(
"PyArray_BOOL");
126 else if (value == PyArray_UINT8)
return std::string(
"PyArray_UINT8");
127 else if (value == PyArray_UINT16)
return std::string(
"PyArray_UINT16");
128 else if (value == PyArray_UINT32)
return std::string(
"PyArray_UINT32");
129 else if (value == PyArray_UINT64)
return std::string(
"PyArray_UINT64");
130 else if (value == PyArray_INT8)
return std::string(
"PyArray_INT8");
131 else if (value == PyArray_INT16)
return std::string(
"PyArray_INT16");
132 else if (value == PyArray_INT32)
return std::string(
"PyArray_INT32");
133 else if (value == PyArray_INT64)
return std::string(
"PyArray_INT64");
134 else if (value == PyArray_FLOAT32)
return std::string(
"PyArray_FLOAT32");
135 else if (value == PyArray_FLOAT64)
return std::string(
"PyArray_FLOAT64");
136 else if (value == PyArray_BYTE)
return std::string(
"PyArray_BYTE");
137 else if (value == PyArray_UBYTE)
return std::string(
"PyArray_UBYTE");
138 else if (value == PyArray_USHORT)
return std::string(
"PyArray_USHORT");
139 else if (value == PyArray_INT)
return std::string(
"PyArray_INT");
140 else if (value == PyArray_UINT)
return std::string(
"PyArray_UINT");
141 else if (value == PyArray_LONG)
return std::string(
"PyArray_LONG");
142 else if (value == PyArray_ULONG)
return std::string(
"PyArray_ULONG");
143 else if (value == PyArray_LONGLONG)
return std::string(
"PyArray_LONGLONG");
144 else if (value == PyArray_DOUBLE)
return std::string(
"PyArray_DOUBLE");
145 else if (value == PyArray_LONGDOUBLE)
return std::string(
"PyArray_LONGDOUBLE");
146 else if (value == PyArray_FLOAT)
return std::string(
"PyArray_FLOAT");
147 else if (value == PyArray_CFLOAT)
return std::string(
"PyArray_CFLOAT");
148 else if (value == PyArray_CDOUBLE)
return std::string(
"PyArray_CDOUBLE");
150 else return " unkown type";
153 template<
class ITERATOR>
155 typedef typename std::iterator_traits<ITERATOR>::value_type ValueType;
156 PyObject* tuple = PyTuple_New(size);
157 if (opengm::meta::Compare<ValueType, opengm::UInt8Type>::value ||
158 opengm::meta::Compare<ValueType, opengm::UInt16Type>::value ||
159 opengm::meta::Compare<ValueType, opengm::UInt32Type>::value ||
160 opengm::meta::Compare<ValueType, opengm::Int8Type>::value ||
161 opengm::meta::Compare<ValueType, opengm::Int16Type>::value ||
162 opengm::meta::Compare<ValueType, opengm::Int32Type>::value
164 for (
size_t i = 0; i<size; ++i) {
165 PyTuple_SetItem(tuple, i, PyInt_FromLong(
long(iter[i])));
168 else if (opengm::meta::Compare<ValueType, opengm::UInt64Type>::value ||
169 opengm::meta::Compare<ValueType, opengm::Int64Type>::value
171 for (
size_t i = 0; i<size; ++i) {
172 PyTuple_SetItem(tuple, i, PyLong_FromLong(
long(iter[i])));
175 else if (opengm::meta::Compare<ValueType, opengm::Float32Type>::value ||
176 opengm::meta::Compare<ValueType, opengm::Float64Type>::value) {
177 for (
size_t i = 0; i<size; ++i) {
178 PyTuple_SetItem(tuple, i, PyFloat_FromDouble(
double(iter[i])));
184 boost::python::tuple t = boost::python::extract<boost::python::tuple > (tuple);
188 template<
class ITERATOR>
190 typedef typename std::iterator_traits<ITERATOR>::value_type ValueType;
191 boost::python::list l;
192 for(
size_t i=0;i<size;++i)
197 template<
class ITERATOR>
199 typedef typename std::iterator_traits<ITERATOR>::value_type ValueType;
200 boost::python::object obj = get1dArray<ValueType>(size);
201 ValueType * castedPtr = getCastedPtr<ValueType>(obj);
202 for(
size_t i=0;i<size;++i)
203 castedPtr[i]=iter[i];
207 template<
class NUMERIC_ARRAY>
209 return PyArray_TYPES(PyArray_TYPE(arr.ptr()));
216 return boost::python::extract<boost::python::numeric::array > (obj);
220 PyArray_Descr* dtype;
221 if (!PyArray_DescrConverter(obj, &dtype))
return NPY_NOTYPE;
222 int typeNum = dtype->type_num;
227 template<
class VALUE_TYPE,
size_t DIM>
233 boost::python::converter::registry::push_back(&convertible, &construct, boost::python::type_id<NumpyViewType > ());
239 if (!PyArray_Check(obj_ptr)) {
246 PyArray_TYPES myEnum = typeEnumFromType<ValueType > ();
247 if (myEnum != pyArrayType) {
248 std::stringstream ss;
249 ss <<
"type mismatch:\n";
250 ss <<
"python type: " <<
printEnum(pyArrayType) <<
"\n";
251 ss <<
"c++ expected type : " <<
printEnum(myEnum);
252 PyErr_SetString(PyExc_ValueError, ss.str().c_str());
256 const boost::python::tuple &shape = boost::python::extract<boost::python::tuple > (numpyArray.attr(
"shape"));
257 if(boost::python::len(shape)!=DIM){
258 std::stringstream ss;
259 ss <<
"dimension mismatch:\n";
260 ss <<
"python numpy dimension : " << boost::python::len(shape) <<
"\n";
261 ss <<
"c++ expected dimension : " << DIM;
262 PyErr_SetString(PyExc_ValueError, ss.str().c_str());
273 boost::python::converter::rvalue_from_python_stage1_data * data) {
278 (boost::python::converter::rvalue_from_python_storage<NumpyViewType>*)
279 data)->storage.bytes;
284 new (storage) NumpyViewType(boost::python::object(boost::python::borrowed(obj_ptr)));
286 data->convertible = storage;
291 template<
class VALUE_TYPE,
size_t DIM>
296 static PyObject *
convert(NumpyViewType numpyView ){
297 return numpyView.object().ptr();
302 template<
class T,
size_t DIM>
static PyObject * convert(NumpyViewType numpyView)
boost::python::numeric::array objToArray(boost::python::object obj)
boost::python::numeric::array extractConstNumericArray(PyObject *obj)
NumpyViewType_from_python_numpyarray()
int numpyScalarTypeNumber(PyObject *obj)
NumpyView< VALUE_TYPE, DIM > NumpyViewType
PyArray_TYPES getArrayType(NUMERIC_ARRAY arr)
NumpyView< ValueType, DIM > NumpyViewType
NPY_TYPES typeEnumFromType< float >(void)
boost::python::list iteratorToList(ITERATOR iter, size_t size)
boost::python::numeric::array iteratorToNumpy(ITERATOR iter, size_t size)
boost::python::object get2dArray(const size_t size1, const size_t size2)
std::string printEnum(PyArray_TYPES value)
boost::python::object getArray(FORWARD_SHAPE_ITERATOR begin, FORWARD_SHAPE_ITERATOR end)
NPY_TYPES typeEnumFromType< bool >(void)
void initializeNumpyViewConverters()
boost::python::tuple iteratorToTuple(ITERATOR iter, size_t size)
static void construct(PyObject *obj_ptr, boost::python::converter::rvalue_from_python_stage1_data *data)
boost::python::object get1dArray(const size_t size)
NPY_TYPES typeEnumFromType< double >(void)
static void * convertible(PyObject *obj_ptr)
VALUE_TYPE * getCastedPtr(boost::python::object obj)
NPY_TYPES typeEnumFromType(void)