mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 22:52:01 +00:00
moved lifetime management of Py_buffer to pybind11::buffer_info, renamed count->size to match NumPy naming (fixes #34)
This commit is contained in:
parent
95d18691c9
commit
d33361a6d7
@ -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)
|
||||
|
@ -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])...);
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user