moved lifetime management of Py_buffer to pybind11::buffer_info, renamed count->size to match NumPy naming (fixes #34)

This commit is contained in:
Wenzel Jakob 2016-01-17 22:36:40 +01:00
parent 95d18691c9
commit d33361a6d7
3 changed files with 29 additions and 22 deletions

View File

@ -144,7 +144,7 @@ PYBIND11_DECL_FMT(float, "f"); PYBIND11_DECL_FMT(double, "d"); PYBIND11_DECL
/// Information record describing a Python buffer object
struct buffer_info {
void *ptr;
size_t itemsize, count;
size_t itemsize, size;
std::string format; // for dense contents, this should be set to format_descriptor<T>::value
int ndim;
std::vector<size_t> shape;
@ -152,10 +152,26 @@ struct buffer_info {
buffer_info(void *ptr, size_t itemsize, const std::string &format, int ndim,
const std::vector<size_t> &shape, const std::vector<size_t> &strides)
: ptr(ptr), itemsize(itemsize), format(format), ndim(ndim),
shape(shape), strides(strides) {
count = 1; for (int i=0; i<ndim; ++i) count *= shape[i];
: ptr(ptr), itemsize(itemsize), size(1), format(format),
ndim(ndim), shape(shape), strides(strides) {
for (int i=0; i<ndim; ++i) size *= shape[i];
}
buffer_info(Py_buffer *view)
: ptr(view->buf), itemsize(view->itemsize), size(1), format(view->format),
ndim(view->ndim), shape(view->ndim), strides(view->ndim), view(view) {
for (int i = 0; i < view->ndim; ++i) {
shape[i] = (size_t) view->shape[i];
strides[i] = (size_t) view->strides[i];
size *= shape[i];
}
}
~buffer_info() {
if (view) { PyBuffer_Release(view); delete view; }
}
private:
Py_buffer *view = nullptr;
};
NAMESPACE_BEGIN(detail)

View File

@ -165,13 +165,13 @@ struct vectorize_helper {
std::array<buffer_info, N> buffers {{ args.request()... }};
/* Determine dimensions parameters of output array */
int ndim = 0; size_t count = 0;
int ndim = 0; size_t size = 0;
std::vector<size_t> shape;
for (size_t i=0; i<N; ++i) {
if (buffers[i].count > count) {
if (buffers[i].size > size) {
ndim = buffers[i].ndim;
shape = buffers[i].shape;
count = buffers[i].count;
size = buffers[i].size;
}
}
std::vector<size_t> strides(ndim);
@ -183,10 +183,10 @@ struct vectorize_helper {
/* Check if the parameters are actually compatible */
for (size_t i=0; i<N; ++i)
if (buffers[i].count != 1 && (buffers[i].ndim != ndim || buffers[i].shape != shape))
if (buffers[i].size != 1 && (buffers[i].ndim != ndim || buffers[i].shape != shape))
throw std::runtime_error("pybind11::vectorize: incompatible size/dimension of inputs!");
if (count == 1)
if (size == 1)
return cast(f(*((Args *) buffers[Index].ptr)...));
array result(buffer_info(nullptr, sizeof(Return),
@ -197,8 +197,8 @@ struct vectorize_helper {
Return *output = (Return *) buf.ptr;
/* Call the function */
for (size_t i=0; i<count; ++i)
output[i] = f((buffers[Index].count == 1
for (size_t i=0; i<size; ++i)
output[i] = f((buffers[Index].size == 1
? *((Args *) buffers[Index].ptr)
: ((Args *) buffers[Index].ptr)[i])...);

View File

@ -418,20 +418,11 @@ public:
buffer_info request(bool writable = false) {
int flags = PyBUF_STRIDES | PyBUF_FORMAT;
if (writable) flags |= PyBUF_WRITABLE;
view = new Py_buffer();
Py_buffer *view = new Py_buffer();
if (PyObject_GetBuffer(m_ptr, view, flags) != 0)
throw error_already_set();
std::vector<size_t> shape(view->ndim), strides(view->ndim);
for (int i=0; i<view->ndim; ++i) {
shape[i] = (size_t) view->shape[i];
strides[i] = (size_t) view->strides[i];
}
return buffer_info(view->buf, view->itemsize, view->format,
view->ndim, shape, strides);
return buffer_info(view);
}
~buffer() { if (view) { PyBuffer_Release(view); delete view; } }
private:
Py_buffer *view = nullptr;
};
NAMESPACE_BEGIN(detail)