example on manually vectorizing numpy code (closes #27)
diff --git a/docs/advanced.rst b/docs/advanced.rst
index 4683c70..d87abc8 100644
--- a/docs/advanced.rst
+++ b/docs/advanced.rst
@@ -473,6 +473,11 @@
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 @@
}
);
+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
diff --git a/docs/changelog.rst b/docs/changelog.rst
index d497e26..0e6161a 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -27,7 +27,7 @@
* 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