Verified Commit fe2240da authored by Justin Carpentier's avatar Justin Carpentier
Browse files

core: add register file

parent 095ebedd
......@@ -122,6 +122,7 @@ SET(${PROJECT_NAME}_HEADERS
include/eigenpy/quaternion.hpp
include/eigenpy/user-type.hpp
include/eigenpy/ufunc.hpp
include/eigenpy/register.hpp
include/eigenpy/stride.hpp
include/eigenpy/version.hpp
)
......@@ -152,7 +153,7 @@ SET(${PROJECT_NAME}_SOURCES
src/matrix-float.cpp
src/matrix-complex-float.cpp
src/matrix-complex-double.cpp
src/user-type.cpp
src/register.cpp
src/matrix-double.cpp
src/matrix-long-double.cpp
src/matrix-complex-long-double.cpp
......
......@@ -7,7 +7,7 @@
#include "eigenpy/fwd.hpp"
#include "eigenpy/numpy-map.hpp"
#include "eigenpy/user-type.hpp"
#include "eigenpy/register.hpp"
#include "eigenpy/scalar-conversion.hpp"
#include "eigenpy/utils/is-aligned.hpp"
......
......@@ -9,7 +9,7 @@
#include "eigenpy/numpy-type.hpp"
#include "eigenpy/eigen-allocator.hpp"
#include "eigenpy/user-type.hpp"
#include "eigenpy/register.hpp"
namespace eigenpy
{
......
//
// Copyright (c) 2020 INRIA
//
#ifndef __eigenpy_register_hpp__
#define __eigenpy_register_hpp__
#include "eigenpy/fwd.hpp"
#include "eigenpy/numpy-type.hpp"
#include "eigenpy/exception.hpp"
#include <algorithm>
#include <map>
#include <typeinfo>
#include <string>
namespace eigenpy
{
/// \brief Structure collecting all the types registers in Numpy via EigenPy
struct EIGENPY_DLLEXPORT Register
{
static PyArray_Descr * getPyArrayDescr(PyTypeObject * py_type_ptr)
{
MapDescr::iterator it = py_array_descr_bindings.find(py_type_ptr);
if(it != py_array_descr_bindings.end())
return it->second;
else
return NULL;
}
template<typename Scalar>
static bool isRegistered()
{
return isRegistered(Register::getPyType<Scalar>());
}
static bool isRegistered(PyTypeObject * py_type_ptr)
{
if(getPyArrayDescr(py_type_ptr) != NULL)
return true;
else
return false;
}
static int getTypeCode(PyTypeObject * py_type_ptr)
{
MapCode::iterator it = py_array_code_bindings.find(py_type_ptr);
if(it != py_array_code_bindings.end())
return it->second;
else
return PyArray_TypeNum(py_type_ptr);
}
template<typename Scalar>
static PyTypeObject * getPyType()
{
if(!isNumpyNativeType<Scalar>())
{
const PyTypeObject * const_py_type_ptr = bp::converter::registered_pytype<Scalar>::get_pytype();
if(const_py_type_ptr == NULL)
{
std::stringstream ss;
ss << "The type " << typeid(Scalar).name() << " does not have a registered converter inside Boot.Python." << std::endl;
throw std::invalid_argument(ss.str());
}
PyTypeObject * py_type_ptr = const_cast<PyTypeObject *>(const_py_type_ptr);
return py_type_ptr;
}
else
{
PyArray_Descr * new_descr = PyArray_DescrFromType(NumpyEquivalentType<Scalar>::type_code);
return new_descr->typeobj;
}
}
template<typename Scalar>
static int getTypeCode()
{
if(isNumpyNativeType<Scalar>())
return NumpyEquivalentType<Scalar>::type_code;
else
{
const std::type_info & info = typeid(Scalar);
if(type_to_py_type_bindings.find(&info) != type_to_py_type_bindings.end())
{
PyTypeObject * py_type = type_to_py_type_bindings[&info];
int code = py_array_code_bindings[py_type];
return code;
}
else
return -1; // type not registered
}
}
static int registerNewType(PyTypeObject * py_type_ptr,
const std::type_info * type_info_ptr,
const int type_size,
PyArray_GetItemFunc * getitem,
PyArray_SetItemFunc * setitem,
PyArray_NonzeroFunc * nonzero,
PyArray_CopySwapFunc * copyswap,
PyArray_CopySwapNFunc * copyswapn,
PyArray_DotFunc * dotfunc)
{
namespace bp = boost::python;
PyArray_Descr * descr_ptr = new PyArray_Descr(*PyArray_DescrFromType(NPY_OBJECT));
PyArray_Descr & descr = *descr_ptr;
descr.typeobj = py_type_ptr;
descr.kind = 'V';
descr.byteorder = '=';
descr.elsize = type_size;
descr.flags = NPY_LIST_PICKLE | NPY_USE_GETITEM | NPY_USE_SETITEM | NPY_NEEDS_INIT | NPY_NEEDS_PYAPI;
// descr->names = PyTuple_New(0);
// descr->fields = PyDict_New();
PyArray_ArrFuncs * funcs_ptr = new PyArray_ArrFuncs;
PyArray_ArrFuncs & funcs = *funcs_ptr;
descr.f = funcs_ptr;
PyArray_InitArrFuncs(funcs_ptr);
funcs.getitem = getitem;
funcs.setitem = setitem;
funcs.nonzero = nonzero;
funcs.copyswap = copyswap;
funcs.copyswapn = copyswapn;
funcs.dotfunc = dotfunc;
// f->cast = cast;
const int code = PyArray_RegisterDataType(descr_ptr);
assert(code >= 0 && "The return code should be positive");
PyArray_Descr * new_descr = PyArray_DescrFromType(code);
type_to_py_type_bindings.insert(std::make_pair(type_info_ptr,py_type_ptr));
py_array_descr_bindings[py_type_ptr] = new_descr;
py_array_code_bindings[py_type_ptr] = code;
// PyArray_RegisterCanCast(descr,NPY_OBJECT,NPY_NOSCALAR);
return code;
}
static Register & instance()
{
return self;
}
private:
Register() {};
struct Compare_PyTypeObject
{
bool operator()(const PyTypeObject * a, const PyTypeObject * b) const
{
return std::string(a->tp_name) < std::string(b->tp_name);
}
};
struct Compare_TypeInfo
{
bool operator()(const std::type_info * a, const std::type_info * b) const
{
return std::string(a->name()) < std::string(b->name());
}
};
typedef std::map<const std::type_info *,PyTypeObject *,Compare_TypeInfo> MapInfo;
static MapInfo type_to_py_type_bindings;
typedef std::map<PyTypeObject *,PyArray_Descr *,Compare_PyTypeObject> MapDescr;
static MapDescr py_array_descr_bindings;
typedef std::map<PyTypeObject *,int,Compare_PyTypeObject> MapCode;
static MapCode py_array_code_bindings;
static Register self;
};
} // namespace eigenpy
#endif // __eigenpy_register_hpp__
......@@ -5,7 +5,7 @@
#ifndef __eigenpy_ufunc_hpp__
#define __eigenpy_ufunc_hpp__
#include "eigenpy/user-type.hpp"
#include "eigenpy/register.hpp"
namespace eigenpy
{
......
......@@ -7,12 +7,7 @@
#include "eigenpy/fwd.hpp"
#include "eigenpy/numpy-type.hpp"
#include "eigenpy/exception.hpp"
#include <algorithm>
#include <map>
#include <typeinfo>
#include <string>
#include "eigenpy/register.hpp"
namespace eigenpy
{
......@@ -171,168 +166,6 @@ namespace eigenpy
} // namespace internal
/// \brief Structure collecting all the types registers in Numpy via EigenPy
struct EIGENPY_DLLEXPORT Register
{
static PyArray_Descr * getPyArrayDescr(PyTypeObject * py_type_ptr)
{
MapDescr::iterator it = py_array_descr_bindings.find(py_type_ptr);
if(it != py_array_descr_bindings.end())
return it->second;
else
return NULL;
}
template<typename Scalar>
static bool isRegistered()
{
return isRegistered(Register::getPyType<Scalar>());
}
static bool isRegistered(PyTypeObject * py_type_ptr)
{
if(getPyArrayDescr(py_type_ptr) != NULL)
return true;
else
return false;
}
static int getTypeCode(PyTypeObject * py_type_ptr)
{
MapCode::iterator it = py_array_code_bindings.find(py_type_ptr);
if(it != py_array_code_bindings.end())
return it->second;
else
return PyArray_TypeNum(py_type_ptr);
}
template<typename Scalar>
static PyTypeObject * getPyType()
{
if(!isNumpyNativeType<Scalar>())
{
const PyTypeObject * const_py_type_ptr = bp::converter::registered_pytype<Scalar>::get_pytype();
if(const_py_type_ptr == NULL)
{
std::stringstream ss;
ss << "The type " << typeid(Scalar).name() << " does not have a registered converter inside Boot.Python." << std::endl;
throw std::invalid_argument(ss.str());
}
PyTypeObject * py_type_ptr = const_cast<PyTypeObject *>(const_py_type_ptr);
return py_type_ptr;
}
else
{
PyArray_Descr * new_descr = PyArray_DescrFromType(NumpyEquivalentType<Scalar>::type_code);
return new_descr->typeobj;
}
}
template<typename Scalar>
static int getTypeCode()
{
if(isNumpyNativeType<Scalar>())
return NumpyEquivalentType<Scalar>::type_code;
else
{
const std::type_info & info = typeid(Scalar);
if(type_to_py_type_bindings.find(&info) != type_to_py_type_bindings.end())
{
PyTypeObject * py_type = type_to_py_type_bindings[&info];
int code = py_array_code_bindings[py_type];
return code;
}
else
return -1; // type not registered
}
}
static int registerNewType(PyTypeObject * py_type_ptr,
const std::type_info * type_info_ptr,
const int type_size,
PyArray_GetItemFunc * getitem,
PyArray_SetItemFunc * setitem,
PyArray_NonzeroFunc * nonzero,
PyArray_CopySwapFunc * copyswap,
PyArray_CopySwapNFunc * copyswapn,
PyArray_DotFunc * dotfunc)
{
namespace bp = boost::python;
PyArray_Descr * descr_ptr = new PyArray_Descr(*PyArray_DescrFromType(NPY_OBJECT));
PyArray_Descr & descr = *descr_ptr;
descr.typeobj = py_type_ptr;
descr.kind = 'V';
descr.byteorder = '=';
descr.elsize = type_size;
descr.flags = NPY_LIST_PICKLE | NPY_USE_GETITEM | NPY_USE_SETITEM | NPY_NEEDS_INIT | NPY_NEEDS_PYAPI;
// descr->names = PyTuple_New(0);
// descr->fields = PyDict_New();
PyArray_ArrFuncs * funcs_ptr = new PyArray_ArrFuncs;
PyArray_ArrFuncs & funcs = *funcs_ptr;
descr.f = funcs_ptr;
PyArray_InitArrFuncs(funcs_ptr);
funcs.getitem = getitem;
funcs.setitem = setitem;
funcs.nonzero = nonzero;
funcs.copyswap = copyswap;
funcs.copyswapn = copyswapn;
funcs.dotfunc = dotfunc;
// f->cast = cast;
const int code = PyArray_RegisterDataType(descr_ptr);
assert(code >= 0 && "The return code should be positive");
PyArray_Descr * new_descr = PyArray_DescrFromType(code);
type_to_py_type_bindings.insert(std::make_pair(type_info_ptr,py_type_ptr));
py_array_descr_bindings[py_type_ptr] = new_descr;
py_array_code_bindings[py_type_ptr] = code;
// PyArray_RegisterCanCast(descr,NPY_OBJECT,NPY_NOSCALAR);
return code;
}
static Register & instance()
{
return self;
}
private:
Register() {};
struct Compare_PyTypeObject
{
bool operator()(const PyTypeObject * a, const PyTypeObject * b) const
{
return std::string(a->tp_name) < std::string(b->tp_name);
}
};
struct Compare_TypeInfo
{
bool operator()(const std::type_info * a, const std::type_info * b) const
{
return std::string(a->name()) < std::string(b->name());
}
};
typedef std::map<const std::type_info *,PyTypeObject *,Compare_TypeInfo> MapInfo;
static MapInfo type_to_py_type_bindings;
typedef std::map<PyTypeObject *,PyArray_Descr *,Compare_PyTypeObject> MapDescr;
static MapDescr py_array_descr_bindings;
typedef std::map<PyTypeObject *,int,Compare_PyTypeObject> MapCode;
static MapCode py_array_code_bindings;
static Register self;
};
template<typename Scalar>
int registerNewType(PyTypeObject * py_type_ptr = NULL)
{
......
......@@ -2,7 +2,7 @@
* Copyright 2020 INRIA
*/
#include "eigenpy/user-type.hpp"
#include "eigenpy/register.hpp"
namespace eigenpy
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment