Skip to content
Snippets Groups Projects
Commit eaebb7ea authored by Wilson Jallet's avatar Wilson Jallet :clapper:
Browse files

eigen-allocator: refactor check of pyArray memory layout vs desired output layout

eigen-allocator: try a fix for mutable Eigen::Ref from Python array with "wrong" layout

* trick transposes pyArray to get the right layout :)
parent 4b433c16
No related branches found
No related tags found
No related merge requests found
...@@ -232,6 +232,22 @@ struct EigenAllocator { ...@@ -232,6 +232,22 @@ struct EigenAllocator {
}; };
#if EIGEN_VERSION_AT_LEAST(3, 2, 0) #if EIGEN_VERSION_AT_LEAST(3, 2, 0)
/// @brief Check if we need to allocate @tparam MatType to convert @param
/// pyArray.
/// @details do not allocate if:
/// want row-major & data C-contiguous OR
/// want col-major & data F-contiguous OR
/// you want a compile-time vector
/// in these cases, data layout fits desired view layout
template <typename MatType>
inline bool is_arr_layout_compatible_with_mat_type(PyArrayObject *pyArray) {
bool is_array_C_cont = PyArray_IS_C_CONTIGUOUS(pyArray);
bool is_array_F_cont = PyArray_IS_F_CONTIGUOUS(pyArray);
return (MatType::IsRowMajor && is_array_C_cont) ||
(!MatType::IsRowMajor && is_array_F_cont) ||
MatType::IsVectorAtCompileTime;
}
template <typename MatType, int Options, typename Stride> template <typename MatType, int Options, typename Stride>
struct EigenAllocator<Eigen::Ref<MatType, Options, Stride> > { struct EigenAllocator<Eigen::Ref<MatType, Options, Stride> > {
typedef Eigen::Ref<MatType, Options, Stride> RefType; typedef Eigen::Ref<MatType, Options, Stride> RefType;
...@@ -255,14 +271,8 @@ struct EigenAllocator<Eigen::Ref<MatType, Options, Stride> > { ...@@ -255,14 +271,8 @@ struct EigenAllocator<Eigen::Ref<MatType, Options, Stride> > {
const int pyArray_type_code = EIGENPY_GET_PY_ARRAY_TYPE(pyArray); const int pyArray_type_code = EIGENPY_GET_PY_ARRAY_TYPE(pyArray);
const int Scalar_type_code = Register::getTypeCode<Scalar>(); const int Scalar_type_code = Register::getTypeCode<Scalar>();
if (pyArray_type_code != Scalar_type_code) need_to_allocate |= true; if (pyArray_type_code != Scalar_type_code) need_to_allocate |= true;
if ((MatType::IsRowMajor && (PyArray_IS_C_CONTIGUOUS(pyArray) && if (is_arr_layout_compatible_with_mat_type<MatType>(pyArray))
!PyArray_IS_F_CONTIGUOUS(pyArray))) || need_to_allocate |= false; // no need to allocate
(!MatType::IsRowMajor && (PyArray_IS_F_CONTIGUOUS(pyArray) &&
!PyArray_IS_C_CONTIGUOUS(pyArray))) ||
MatType::IsVectorAtCompileTime ||
(PyArray_IS_F_CONTIGUOUS(pyArray) &&
PyArray_IS_C_CONTIGUOUS(pyArray))) // no need to allocate
need_to_allocate |= false;
else else
need_to_allocate |= true; need_to_allocate |= true;
if (Options != if (Options !=
...@@ -276,6 +286,10 @@ struct EigenAllocator<Eigen::Ref<MatType, Options, Stride> > { ...@@ -276,6 +286,10 @@ struct EigenAllocator<Eigen::Ref<MatType, Options, Stride> > {
void *raw_ptr = storage->storage.bytes; void *raw_ptr = storage->storage.bytes;
if (need_to_allocate) { if (need_to_allocate) {
PyObject *pyarr_transposed = PyArray_Transpose(pyArray, NULL);
allocate((PyArrayObject *)pyarr_transposed, storage);
/*
std::cout << " doing allocate\n";
MatType *mat_ptr; MatType *mat_ptr;
mat_ptr = details::init_matrix_or_array<MatType>::run(pyArray); mat_ptr = details::init_matrix_or_array<MatType>::run(pyArray);
RefType mat_ref(*mat_ptr); RefType mat_ref(*mat_ptr);
...@@ -326,6 +340,7 @@ struct EigenAllocator<Eigen::Ref<MatType, Options, Stride> > { ...@@ -326,6 +340,7 @@ struct EigenAllocator<Eigen::Ref<MatType, Options, Stride> > {
throw Exception( throw Exception(
"You asked for a conversion which is not implemented."); "You asked for a conversion which is not implemented.");
} }
*/
} else { } else {
assert(pyArray_type_code == Scalar_type_code); assert(pyArray_type_code == Scalar_type_code);
typename NumpyMap<MatType, Scalar, Options, NumpyMapStride>::EigenMap typename NumpyMap<MatType, Scalar, Options, NumpyMapStride>::EigenMap
...@@ -365,14 +380,8 @@ struct EigenAllocator<const Eigen::Ref<const MatType, Options, Stride> > { ...@@ -365,14 +380,8 @@ struct EigenAllocator<const Eigen::Ref<const MatType, Options, Stride> > {
const int Scalar_type_code = Register::getTypeCode<Scalar>(); const int Scalar_type_code = Register::getTypeCode<Scalar>();
if (pyArray_type_code != Scalar_type_code) need_to_allocate |= true; if (pyArray_type_code != Scalar_type_code) need_to_allocate |= true;
if ((MatType::IsRowMajor && (PyArray_IS_C_CONTIGUOUS(pyArray) && if (is_arr_layout_compatible_with_mat_type<MatType>(pyArray))
!PyArray_IS_F_CONTIGUOUS(pyArray))) || need_to_allocate |= false; // no need to allocate
(!MatType::IsRowMajor && (PyArray_IS_F_CONTIGUOUS(pyArray) &&
!PyArray_IS_C_CONTIGUOUS(pyArray))) ||
MatType::IsVectorAtCompileTime ||
(PyArray_IS_F_CONTIGUOUS(pyArray) &&
PyArray_IS_C_CONTIGUOUS(pyArray))) // no need to allocate
need_to_allocate |= false;
else else
need_to_allocate |= true; need_to_allocate |= true;
if (Options != if (Options !=
......
...@@ -76,9 +76,10 @@ print("-----------------") ...@@ -76,9 +76,10 @@ print("-----------------")
print("l3:") print("l3:")
vector.setZero(l3) vector.setZero(l3)
pprint.pp(list(l3)) pprint.pp(list(l3))
# checkZero(l3) checkZero(l3)
print("-----------------") print("-----------------")
print("l4:") print("l4:")
vector.setZero(l4) vector.setZero(l4)
pprint.pp(list(l4)) pprint.pp(list(l4))
checkZero(l4)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment