diff --git a/docs/advanced.rst b/docs/advanced.rst index 4683c7086..d87abc8ae 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -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 + #include + + namespace py = pybind11; + + py::array_t add_arrays(py::array_t input1, py::array_t 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::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 d497e26a7..0e6161a87 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -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