Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions 11 include/ndarray/converter/eigen.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ template <typename T, int N, int C, typename XprKind_, int Rows_, int Cols_>
struct PyConverter< EigenView<T,N,C,XprKind_,Rows_,Cols_> > {

static bool fromPythonStage1(PyPtr & p) {
auto array = reinterpret_cast<PyArrayObject*>(p.get());
// add or remove dimensions with size one so we have the right number of dimensions
if (PyArray_Check(p.get())) {
if ((Rows_ == 1 || Cols_ == 1) && N == 2) {
Expand All @@ -40,29 +41,29 @@ struct PyConverter< EigenView<T,N,C,XprKind_,Rows_,Cols_> > {
shape[1] = 1;
}
PyArray_Dims dims = { shape, 2 };
PyPtr r(PyArray_Newshape(reinterpret_cast<PyArrayObject*>(p.get()), &dims, NPY_ANYORDER));
PyPtr r(PyArray_Newshape(array, &dims, NPY_ANYORDER));
if (!r) return false;
p.swap(r);
} else if (N == 1) {
PyPtr r(PyArray_Squeeze(reinterpret_cast<PyArrayObject*>(p.get())));
PyPtr r(PyArray_Squeeze(array));
if (!r) return false;
p.swap(r);
}
} // else let the Array converter raise the exception
if (!PyConverter< Array<T,N,C> >::fromPythonStage1(p)) return false;
// check whether the size is correct if it's static
if (N == 2) {
if (Rows_ != Eigen::Dynamic && PyArray_DIM(p.get(), 0) != Rows_) {
if (Rows_ != Eigen::Dynamic && PyArray_DIM(array, 0) != Rows_) {
PyErr_SetString(PyExc_ValueError, "incorrect number of rows for matrix");
return false;
}
if (Cols_ != Eigen::Dynamic && PyArray_DIM(p.get(), 1) != Cols_) {
if (Cols_ != Eigen::Dynamic && PyArray_DIM(array, 1) != Cols_) {
PyErr_SetString(PyExc_ValueError, "incorrect number of columns for matrix");
return false;
}
} else {
int requiredSize = Rows_ * Cols_;
if (requiredSize != Eigen::Dynamic && PyArray_SIZE(p.get()) != requiredSize) {
if (requiredSize != Eigen::Dynamic && PyArray_SIZE(array) != requiredSize) {
PyErr_SetString(PyExc_ValueError, "incorrect number of elements for vector");
return false;
}
Expand Down
42 changes: 24 additions & 18 deletions 42 include/ndarray/converter/numpy.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#ifndef NDARRAY_CONVERTER_numpy_h_INCLUDED
#define NDARRAY_CONVERTER_numpy_h_INCLUDED

#ifndef NPY_NO_DEPRECATED_API
#pragma message ( "ndarray is compatible with the NumPy 1.7 API, define NPY_NO_DEPRECATED_API to suppress API version warnings" )
#endif

/**
* @file ndarray/converter/numpy.h
* @brief Python C-API conversions between ndarray and numpy.
Expand Down Expand Up @@ -155,46 +159,47 @@ struct PyConverter< Array<T,N,C> > : public detail::PyConverterBase< Array<T,N,C
PyErr_SetString(PyExc_TypeError, "numpy.ndarray argument required");
return false;
}
int actualType = PyArray_TYPE(p.get());
auto array = reinterpret_cast<PyArrayObject*>(p.get());
int actualType = PyArray_TYPE(array);
int requiredType = detail::NumpyTraits<NonConst>::getCode();
if (actualType != requiredType) {
PyErr_SetString(PyExc_ValueError, ("numpy.ndarray argument has incorrect data type"));
return false;
}
if (PyArray_NDIM(p.get()) != N) {
if (PyArray_NDIM(array) != N) {
PyErr_SetString(PyExc_ValueError, "numpy.ndarray argument has incorrect number of dimensions");
return false;
}
bool writeable = !boost::is_const<Element>::value;
if (writeable && !(PyArray_FLAGS(p.get()) & NPY_WRITEABLE)) {
if (writeable && !(PyArray_FLAGS(array) & NPY_ARRAY_WRITEABLE)) {
PyErr_SetString(PyExc_TypeError, "numpy.ndarray argument must be writeable");
return false;
}
if (C > 0) {
Offset requiredStride = sizeof(Element);
for (int i = 0; i < C; ++i) {
Offset actualStride = PyArray_STRIDE(p.get(), N-i-1);
Offset actualStride = PyArray_STRIDE(array, N-i-1);
if (actualStride != requiredStride) {
PyErr_SetString(
PyExc_ValueError,
"numpy.ndarray does not have enough row-major contiguous dimensions"
);
return false;
}
requiredStride *= PyArray_DIM(p.get(), N-i-1);
requiredStride *= PyArray_DIM(array, N-i-1);
}
} else if (C < 0) {
int requiredStride = sizeof(Element);
for (int i = 0; i < -C; ++i) {
Offset actualStride = PyArray_STRIDE(p.get(), i);
Offset actualStride = PyArray_STRIDE(array, i);
if (actualStride != requiredStride) {
PyErr_SetString(
PyExc_ValueError,
"numpy.ndarray does not have enough column-major contiguous dimensions"
);
return false;
}
requiredStride *= PyArray_DIM(p.get(), i);
requiredStride *= PyArray_DIM(array, i);
}
}
return true;
Expand All @@ -216,13 +221,14 @@ struct PyConverter< Array<T,N,C> > : public detail::PyConverterBase< Array<T,N,C
PyPtr const & input, ///< Result of fromPythonStage1().
Array<T,N,C> & output ///< Reference to existing output C++ object.
) {
if (!(PyArray_FLAGS(input.get()) & NPY_ALIGNED)) {
auto array = reinterpret_cast<PyArrayObject*>(input.get());
if (!(PyArray_FLAGS(array) & NPY_ARRAY_ALIGNED)) {
PyErr_SetString(PyExc_TypeError, "unaligned arrays cannot be converted to C++");
return false;
}
Offset itemsize = sizeof(Element);
for (int i = 0; i < N; ++i) {
if ((PyArray_DIM(input.get(), i) > 1) && (PyArray_STRIDE(input.get(), i) % itemsize != 0)) {
if ((PyArray_DIM(array, i) > 1) && (PyArray_STRIDE(array, i) % itemsize != 0)) {
PyErr_SetString(
PyExc_TypeError,
"Cannot convert array to C++: strides must be an integer multiple of the element size"
Expand All @@ -232,11 +238,11 @@ struct PyConverter< Array<T,N,C> > : public detail::PyConverterBase< Array<T,N,C
}
Vector<Size,N> shape;
Vector<Offset,N> strides;
std::copy(PyArray_DIMS(input.get()), PyArray_DIMS(input.get()) + N, shape.begin());
std::copy(PyArray_STRIDES(input.get()), PyArray_STRIDES(input.get()) + N , strides.begin());
std::copy(PyArray_DIMS(array), PyArray_DIMS(array) + N, shape.begin());
std::copy(PyArray_STRIDES(array), PyArray_STRIDES(array) + N , strides.begin());
for (int i = 0; i < N; ++i) strides[i] /= sizeof(Element);
output = external(
reinterpret_cast<Element*>(PyArray_DATA(input.get())),
reinterpret_cast<Element*>(PyArray_DATA(array)),
shape, strides, input
);
return true;
Expand All @@ -257,10 +263,10 @@ struct PyConverter< Array<T,N,C> > : public detail::PyConverterBase< Array<T,N,C
PyObject* owner=NULL /**< A Python object that owns the memory in the Array.
* If NULL, one will be constructed from m.getManager(). */
) {
int flags = NPY_ALIGNED;
if (C==N) flags |= NPY_C_CONTIGUOUS;
int flags = NPY_ARRAY_ALIGNED;
if (C==N) flags |= NPY_ARRAY_C_CONTIGUOUS;
bool writeable = !boost::is_const<Element>::value;
if (writeable) flags |= NPY_WRITEABLE;
if (writeable) flags |= NPY_ARRAY_WRITEABLE;
npy_intp outShape[N];
npy_intp outStrides[N];
Vector<Size,N> inShape = m.getShape();
Expand All @@ -276,8 +282,8 @@ struct PyConverter< Array<T,N,C> > : public detail::PyConverterBase< Array<T,N,C
);
if (!array) return NULL;
if (!m.getManager() && owner == NULL) {
flags = NPY_CARRAY_RO | NPY_ENSURECOPY | NPY_C_CONTIGUOUS;
if (writeable) flags |= NPY_WRITEABLE;
flags = NPY_ARRAY_CARRAY_RO | NPY_ARRAY_ENSURECOPY | NPY_ARRAY_C_CONTIGUOUS;
if (writeable) flags |= NPY_ARRAY_WRITEABLE;
PyPtr r = PyArray_FROM_OF(array.get(),flags);
if (!r) return NULL;
array.swap(r);
Expand All @@ -291,7 +297,7 @@ struct PyConverter< Array<T,N,C> > : public detail::PyConverterBase< Array<T,N,C
detail::destroyCapsule
);
}
reinterpret_cast<PyArrayObject*>(array.get())->base = owner;
PyArray_SetBaseObject(reinterpret_cast<PyArrayObject*>(array.get()), owner);
}
Py_INCREF(array.get());
return PyArray_Return(reinterpret_cast<PyArrayObject*>(array.get()));
Expand Down
14 changes: 7 additions & 7 deletions 14 include/ndarray/converter/ufunctors.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ template <typename TUnaryFunctor,
struct PyUnaryUFunctor {

static PyObject* _call_(TUnaryFunctor const& self, PyObject* input, PyObject* output) {
PyObject* input_array = PyArray_FROM_OTF(input,detail::NumpyTraits<TArgument>::getCode(),
NPY_ALIGNED);
PyArrayObject* input_array = PyArray_FROM_OTF(input,detail::NumpyTraits<TArgument>::getCode(),
NPY_ARRAY_ALIGNED);
if (input_array == NULL) return NULL;
PyObject* output_array;
PyArrayObject* output_array;
if (output == NULL || output == Py_None) {
output_array = PyArray_SimpleNew(PyArray_NDIM(input_array),
PyArray_DIMS(input_array),
detail::NumpyTraits<TResult>::getCode());
} else {
output_array = PyArray_FROM_OTF(output,detail::NumpyTraits<TResult>::getCode(),
NPY_ALIGNED | NPY_WRITEABLE | NPY_UPDATEIFCOPY);
NPY_ARRAY_ALIGNED | NPY_ARRAY_WRITEABLE | NPY_ARRAY_UPDATEIFCOPY);
}
if (output_array == NULL) {
Py_DECREF(input_array);
Expand Down Expand Up @@ -72,9 +72,9 @@ struct PyBinaryUFunctor {
static PyObject* _call_(TBinaryFunctor const& self, PyObject* input1, PyObject* input2,
PyObject* output) {
PyObject* input1_array = PyArray_FROM_OTF(input1,detail::NumpyTraits<TArgument1>::getCode(),
NPY_ALIGNED);
NPY_ARRAY_ALIGNED);
PyObject* input2_array = PyArray_FROM_OTF(input2,detail::NumpyTraits<TArgument1>::getCode(),
NPY_ALIGNED);
NPY_ARRAY_ALIGNED);
if (input1_array == NULL || input2_array == NULL) {
Py_XDECREF(input1_array);
Py_XDECREF(input2_array);
Expand All @@ -94,7 +94,7 @@ struct PyBinaryUFunctor {
Py_DECREF(tmp);
} else {
output_array = PyArray_FROM_OTF(output,detail::NumpyTraits<TResult>::getCode(),
NPY_ALIGNED | NPY_WRITEABLE | NPY_UPDATEIFCOPY);
NPY_ARRAY_ALIGNED | NPY_ARRAY_WRITEABLE | NPY_ARRAY_UPDATEIFCOPY);
}
if (output_array == NULL) {
Py_DECREF(input1_array);
Expand Down
1 change: 1 addition & 0 deletions 1 tests/pybind11_test_mod.cc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include "pybind11/pybind11.h"

#include "numpy/arrayobject.h"
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.