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 {
};
#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>
struct EigenAllocator<Eigen::Ref<MatType, Options, Stride> > {
typedef Eigen::Ref<MatType, Options, Stride> RefType;
......@@ -255,14 +271,8 @@ struct EigenAllocator<Eigen::Ref<MatType, Options, Stride> > {
const int pyArray_type_code = EIGENPY_GET_PY_ARRAY_TYPE(pyArray);
const int Scalar_type_code = Register::getTypeCode<Scalar>();
if (pyArray_type_code != Scalar_type_code) need_to_allocate |= true;
if ((MatType::IsRowMajor && (PyArray_IS_C_CONTIGUOUS(pyArray) &&
!PyArray_IS_F_CONTIGUOUS(pyArray))) ||
(!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;
if (is_arr_layout_compatible_with_mat_type<MatType>(pyArray))
need_to_allocate |= false; // no need to allocate
else
need_to_allocate |= true;
if (Options !=
......@@ -276,6 +286,10 @@ struct EigenAllocator<Eigen::Ref<MatType, Options, Stride> > {
void *raw_ptr = storage->storage.bytes;
if (need_to_allocate) {
PyObject *pyarr_transposed = PyArray_Transpose(pyArray, NULL);
allocate((PyArrayObject *)pyarr_transposed, storage);
/*
std::cout << " doing allocate\n";
MatType *mat_ptr;
mat_ptr = details::init_matrix_or_array<MatType>::run(pyArray);
RefType mat_ref(*mat_ptr);
......@@ -326,6 +340,7 @@ struct EigenAllocator<Eigen::Ref<MatType, Options, Stride> > {
throw Exception(
"You asked for a conversion which is not implemented.");
}
*/
} else {
assert(pyArray_type_code == Scalar_type_code);
typename NumpyMap<MatType, Scalar, Options, NumpyMapStride>::EigenMap
......@@ -365,14 +380,8 @@ struct EigenAllocator<const Eigen::Ref<const MatType, Options, Stride> > {
const int Scalar_type_code = Register::getTypeCode<Scalar>();
if (pyArray_type_code != Scalar_type_code) need_to_allocate |= true;
if ((MatType::IsRowMajor && (PyArray_IS_C_CONTIGUOUS(pyArray) &&
!PyArray_IS_F_CONTIGUOUS(pyArray))) ||
(!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;
if (is_arr_layout_compatible_with_mat_type<MatType>(pyArray))
need_to_allocate |= false; // no need to allocate
else
need_to_allocate |= true;
if (Options !=
......
......@@ -76,9 +76,10 @@ print("-----------------")
print("l3:")
vector.setZero(l3)
pprint.pp(list(l3))
# checkZero(l3)
checkZero(l3)
print("-----------------")
print("l4:")
vector.setZero(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