mirror of
https://github.com/RYDE-WORK/pybind11.git
synced 2026-02-05 23:13:36 +08: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
|
/// Information record describing a Python buffer object
|
||||||
struct buffer_info {
|
struct buffer_info {
|
||||||
void *ptr;
|
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
|
std::string format; // for dense contents, this should be set to format_descriptor<T>::value
|
||||||
int ndim;
|
int ndim;
|
||||||
std::vector<size_t> shape;
|
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,
|
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)
|
const std::vector<size_t> &shape, const std::vector<size_t> &strides)
|
||||||
: ptr(ptr), itemsize(itemsize), format(format), ndim(ndim),
|
: ptr(ptr), itemsize(itemsize), size(1), format(format),
|
||||||
shape(shape), strides(strides) {
|
ndim(ndim), shape(shape), strides(strides) {
|
||||||
count = 1; for (int i=0; i<ndim; ++i) count *= shape[i];
|
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)
|
NAMESPACE_BEGIN(detail)
|
||||||
|
|||||||
@ -165,13 +165,13 @@ struct vectorize_helper {
|
|||||||
std::array<buffer_info, N> buffers {{ args.request()... }};
|
std::array<buffer_info, N> buffers {{ args.request()... }};
|
||||||
|
|
||||||
/* Determine dimensions parameters of output array */
|
/* 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;
|
std::vector<size_t> shape;
|
||||||
for (size_t i=0; i<N; ++i) {
|
for (size_t i=0; i<N; ++i) {
|
||||||
if (buffers[i].count > count) {
|
if (buffers[i].size > size) {
|
||||||
ndim = buffers[i].ndim;
|
ndim = buffers[i].ndim;
|
||||||
shape = buffers[i].shape;
|
shape = buffers[i].shape;
|
||||||
count = buffers[i].count;
|
size = buffers[i].size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::vector<size_t> strides(ndim);
|
std::vector<size_t> strides(ndim);
|
||||||
@ -183,10 +183,10 @@ struct vectorize_helper {
|
|||||||
|
|
||||||
/* Check if the parameters are actually compatible */
|
/* Check if the parameters are actually compatible */
|
||||||
for (size_t i=0; i<N; ++i)
|
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!");
|
throw std::runtime_error("pybind11::vectorize: incompatible size/dimension of inputs!");
|
||||||
|
|
||||||
if (count == 1)
|
if (size == 1)
|
||||||
return cast(f(*((Args *) buffers[Index].ptr)...));
|
return cast(f(*((Args *) buffers[Index].ptr)...));
|
||||||
|
|
||||||
array result(buffer_info(nullptr, sizeof(Return),
|
array result(buffer_info(nullptr, sizeof(Return),
|
||||||
@ -197,8 +197,8 @@ struct vectorize_helper {
|
|||||||
Return *output = (Return *) buf.ptr;
|
Return *output = (Return *) buf.ptr;
|
||||||
|
|
||||||
/* Call the function */
|
/* Call the function */
|
||||||
for (size_t i=0; i<count; ++i)
|
for (size_t i=0; i<size; ++i)
|
||||||
output[i] = f((buffers[Index].count == 1
|
output[i] = f((buffers[Index].size == 1
|
||||||
? *((Args *) buffers[Index].ptr)
|
? *((Args *) buffers[Index].ptr)
|
||||||
: ((Args *) buffers[Index].ptr)[i])...);
|
: ((Args *) buffers[Index].ptr)[i])...);
|
||||||
|
|
||||||
|
|||||||
@ -418,20 +418,11 @@ public:
|
|||||||
buffer_info request(bool writable = false) {
|
buffer_info request(bool writable = false) {
|
||||||
int flags = PyBUF_STRIDES | PyBUF_FORMAT;
|
int flags = PyBUF_STRIDES | PyBUF_FORMAT;
|
||||||
if (writable) flags |= PyBUF_WRITABLE;
|
if (writable) flags |= PyBUF_WRITABLE;
|
||||||
view = new Py_buffer();
|
Py_buffer *view = new Py_buffer();
|
||||||
if (PyObject_GetBuffer(m_ptr, view, flags) != 0)
|
if (PyObject_GetBuffer(m_ptr, view, flags) != 0)
|
||||||
throw error_already_set();
|
throw error_already_set();
|
||||||
std::vector<size_t> shape(view->ndim), strides(view->ndim);
|
return buffer_info(view);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
~buffer() { if (view) { PyBuffer_Release(view); delete view; } }
|
|
||||||
private:
|
|
||||||
Py_buffer *view = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NAMESPACE_BEGIN(detail)
|
NAMESPACE_BEGIN(detail)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user