Merge pull request #267 from bennorth/non-contiguous-arrays

Non-contiguous arrays
This commit is contained in:
Wenzel Jakob 2016-07-05 22:34:36 +02:00 committed by GitHub
commit c2f6841c22
4 changed files with 55 additions and 3 deletions

View File

@ -10,6 +10,19 @@
#include "example.h" #include "example.h"
#include <pybind11/eigen.h> #include <pybind11/eigen.h>
Eigen::VectorXf double_col(const Eigen::VectorXf& x)
{ return 2.0f * x; }
Eigen::RowVectorXf double_row(const Eigen::RowVectorXf& x)
{ return 2.0f * x; }
Eigen::MatrixXf double_mat_cm(const Eigen::MatrixXf& x)
{ return 2.0f * x; }
typedef Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> MatrixXfRowMajor;
MatrixXfRowMajor double_mat_rm(const MatrixXfRowMajor& x)
{ return 2.0f * x; }
void init_eigen(py::module &m) { void init_eigen(py::module &m) {
typedef Eigen::Matrix<float, 5, 6, Eigen::RowMajor> FixedMatrixR; typedef Eigen::Matrix<float, 5, 6, Eigen::RowMajor> FixedMatrixR;
typedef Eigen::Matrix<float, 5, 6> FixedMatrixC; typedef Eigen::Matrix<float, 5, 6> FixedMatrixC;
@ -23,6 +36,11 @@ void init_eigen(py::module &m) {
mat << 0, 3, 0, 0, 0, 11, 22, 0, 0, 0, 17, 11, 7, 5, 0, 1, 0, 11, 0, mat << 0, 3, 0, 0, 0, 11, 22, 0, 0, 0, 17, 11, 7, 5, 0, 1, 0, 11, 0,
0, 0, 0, 0, 11, 0, 0, 14, 0, 8, 11; 0, 0, 0, 0, 11, 0, 0, 14, 0, 8, 11;
m.def("double_col", &double_col);
m.def("double_row", &double_row);
m.def("double_mat_cm", &double_mat_cm);
m.def("double_mat_rm", &double_mat_rm);
m.def("fixed_r", [mat]() -> FixedMatrixR { m.def("fixed_r", [mat]() -> FixedMatrixR {
return FixedMatrixR(mat); return FixedMatrixR(mat);
}); });

View File

@ -9,6 +9,8 @@ from example import dense_r, dense_c
from example import dense_passthrough_r, dense_passthrough_c from example import dense_passthrough_r, dense_passthrough_c
from example import sparse_r, sparse_c from example import sparse_r, sparse_c
from example import sparse_passthrough_r, sparse_passthrough_c from example import sparse_passthrough_r, sparse_passthrough_c
from example import double_row, double_col
from example import double_mat_cm, double_mat_rm
import numpy as np import numpy as np
ref = np.array( ref = np.array(
@ -42,3 +44,22 @@ print("pt_r(sparse_r) = %s" % check(sparse_passthrough_r(sparse_r())))
print("pt_c(sparse_c) = %s" % check(sparse_passthrough_c(sparse_c()))) print("pt_c(sparse_c) = %s" % check(sparse_passthrough_c(sparse_c())))
print("pt_r(sparse_c) = %s" % check(sparse_passthrough_r(sparse_c()))) print("pt_r(sparse_c) = %s" % check(sparse_passthrough_r(sparse_c())))
print("pt_c(sparse_r) = %s" % check(sparse_passthrough_c(sparse_r()))) print("pt_c(sparse_r) = %s" % check(sparse_passthrough_c(sparse_r())))
def check_got_vs_ref(got_x, ref_x):
return 'OK' if np.array_equal(got_x, ref_x) else 'NOT OK'
counting_mat = np.arange(9.0, dtype=np.float32).reshape((3, 3))
first_row = counting_mat[0, :]
first_col = counting_mat[:, 0]
print("double_row(first_row) = %s" % check_got_vs_ref(double_row(first_row), 2.0 * first_row))
print("double_col(first_row) = %s" % check_got_vs_ref(double_col(first_row), 2.0 * first_row))
print("double_row(first_col) = %s" % check_got_vs_ref(double_row(first_col), 2.0 * first_col))
print("double_col(first_col) = %s" % check_got_vs_ref(double_col(first_col), 2.0 * first_col))
counting_3d = np.arange(27.0, dtype=np.float32).reshape((3, 3, 3))
slices = [counting_3d[0, :, :], counting_3d[:, 0, :], counting_3d[:, :, 0]]
for slice_idx, ref_mat in enumerate(slices):
print("double_mat_cm(%d) = %s" % (slice_idx, check_got_vs_ref(double_mat_cm(ref_mat), 2.0 * ref_mat)))
print("double_mat_rm(%d) = %s" % (slice_idx, check_got_vs_ref(double_mat_rm(ref_mat), 2.0 * ref_mat)))

View File

@ -16,3 +16,13 @@ pt_r(sparse_r) = OK
pt_c(sparse_c) = OK pt_c(sparse_c) = OK
pt_r(sparse_c) = OK pt_r(sparse_c) = OK
pt_c(sparse_r) = OK pt_c(sparse_r) = OK
double_row(first_row) = OK
double_col(first_row) = OK
double_row(first_col) = OK
double_col(first_col) = OK
double_mat_cm(0) = OK
double_mat_rm(0) = OK
double_mat_cm(1) = OK
double_mat_rm(1) = OK
double_mat_cm(2) = OK
double_mat_rm(2) = OK

View File

@ -61,7 +61,7 @@ struct type_caster<Type, typename std::enable_if<is_eigen_dense<Type>::value>::t
buffer_info info = buffer.request(); buffer_info info = buffer.request();
if (info.ndim == 1) { if (info.ndim == 1) {
typedef Eigen::Stride<Eigen::Dynamic, 0> Strides; typedef Eigen::InnerStride<> Strides;
if (!isVector && if (!isVector &&
!(Type::RowsAtCompileTime == Eigen::Dynamic && !(Type::RowsAtCompileTime == Eigen::Dynamic &&
Type::ColsAtCompileTime == Eigen::Dynamic)) Type::ColsAtCompileTime == Eigen::Dynamic))
@ -71,10 +71,13 @@ struct type_caster<Type, typename std::enable_if<is_eigen_dense<Type>::value>::t
info.shape[0] != (size_t) Type::SizeAtCompileTime) info.shape[0] != (size_t) Type::SizeAtCompileTime)
return false; return false;
auto strides = Strides(info.strides[0] / sizeof(Scalar), 0); auto strides = Strides(info.strides[0] / sizeof(Scalar));
Strides::Index n_elts = info.shape[0];
Strides::Index unity = 1;
value = Eigen::Map<Type, 0, Strides>( value = Eigen::Map<Type, 0, Strides>(
(Scalar *) info.ptr, typename Strides::Index(info.shape[0]), 1, strides); (Scalar *) info.ptr, rowMajor ? unity : n_elts, rowMajor ? n_elts : unity, strides);
} else if (info.ndim == 2) { } else if (info.ndim == 2) {
typedef Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic> Strides; typedef Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic> Strides;