mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-11 08:03:55 +00:00
example on manually vectorizing numpy code (closes #27)
This commit is contained in:
parent
260bc58f57
commit
61587164ed
@ -473,6 +473,11 @@ follows:
|
||||
Patient != 0) and ``with_custodian_and_ward_postcall`` (if Nurse/Patient ==
|
||||
0) policies from Boost.Python.
|
||||
|
||||
.. seealso::
|
||||
|
||||
The file :file:`example/example13.cpp` contains a complete example that
|
||||
demonstrates using :class:`keep_alive` in more detail.
|
||||
|
||||
Implicit type conversions
|
||||
=========================
|
||||
|
||||
@ -850,6 +855,55 @@ This can be done with a stateful Lambda closure:
|
||||
}
|
||||
);
|
||||
|
||||
In cases where the computation is too complicated to be reduced to
|
||||
``vectorize``, it will be necessary to create and access the buffer contents
|
||||
manually. The following snippet contains a complete example that shows how this
|
||||
works (the code is somewhat contrived, since it could have been done more
|
||||
simply using ``vectorize``).
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/numpy.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
py::array_t<double> add_arrays(py::array_t<double> input1, py::array_t<double> input2) {
|
||||
auto buf1 = input1.request(), buf2 = input2.request();
|
||||
|
||||
if (buf1.ndim != 1 || buf2.ndim != 1)
|
||||
throw std::runtime_error("Number of dimensions must be one");
|
||||
|
||||
if (buf1.shape[0] != buf2.shape[0])
|
||||
throw std::runtime_error("Input shapes must match");
|
||||
|
||||
auto result = py::array(py::buffer_info(
|
||||
nullptr, /* Pointer to data (nullptr -> ask NumPy to allocate!) */
|
||||
sizeof(double), /* Size of one item */
|
||||
py::format_descriptor<double>::value(), /* Buffer format */
|
||||
buf1.ndim, /* How many dimensions? */
|
||||
{ buf1.shape[0] }, /* Number of elements for each dimension */
|
||||
{ sizeof(double) } /* Strides for each dimension */
|
||||
));
|
||||
|
||||
auto buf3 = result.request();
|
||||
|
||||
double *ptr1 = (double *) buf1.ptr,
|
||||
*ptr2 = (double *) buf2.ptr,
|
||||
*ptr3 = (double *) buf3.ptr;
|
||||
|
||||
for (size_t idx = 0; idx < buf1.shape[0]; idx++)
|
||||
ptr3[idx] = ptr1[idx] + ptr2[idx];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PYBIND11_PLUGIN(test) {
|
||||
py::module m("test");
|
||||
m.def("add_arrays", &add_arrays, "Add two NumPy arrays");
|
||||
return m.ptr();
|
||||
}
|
||||
|
||||
.. seealso::
|
||||
|
||||
The file :file:`example/example10.cpp` contains a complete example that
|
||||
|
@ -27,7 +27,7 @@ Changelog
|
||||
* Added conversions for additional exception types
|
||||
* Documentation improvements (using multiple extension modules, smart pointers,
|
||||
other minor clarifications)
|
||||
* unified infrastructure for parsing variadic arguments in class_ and cpp_function
|
||||
* unified infrastructure for parsing variadic arguments in ``class_`` and cpp_function
|
||||
* Fixed license text (was: ZLIB, should have been: 3-clause BSD)
|
||||
* Python 3.2 compatibility
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user