mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 14:45:12 +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 ==
|
Patient != 0) and ``with_custodian_and_ward_postcall`` (if Nurse/Patient ==
|
||||||
0) policies from Boost.Python.
|
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
|
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::
|
.. seealso::
|
||||||
|
|
||||||
The file :file:`example/example10.cpp` contains a complete example that
|
The file :file:`example/example10.cpp` contains a complete example that
|
||||||
|
@ -27,7 +27,7 @@ Changelog
|
|||||||
* Added conversions for additional exception types
|
* Added conversions for additional exception types
|
||||||
* Documentation improvements (using multiple extension modules, smart pointers,
|
* Documentation improvements (using multiple extension modules, smart pointers,
|
||||||
other minor clarifications)
|
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)
|
* Fixed license text (was: ZLIB, should have been: 3-clause BSD)
|
||||||
* Python 3.2 compatibility
|
* Python 3.2 compatibility
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user