Use pybind11 in image module#26275
Conversation
| (type == NPY_INT16) ? resample<agg::gray16> : | ||
| (type == NPY_FLOAT32) ? resample<agg::gray32> : | ||
| (type == NPY_FLOAT64) ? resample<agg::gray64> : | ||
| (dtype.is(pybind11::dtype::of<std::uint8_t>())) ? resample<agg::gray8> : |
There was a problem hiding this comment.
This is more verbose than it used to be, but is the recommended way of checking dtypes in pybind11.
There was a problem hiding this comment.
At SciPy Conf 2023, I asked Henry (pybind11 maintainer) if there was a less verbose way to do this type of check and he said this was the best way.
22a0788 to
ce7afe1
Compare
|
I cannot really review it properly, but I am positive to the effort! Are the failing tests somehow related? It seems like they may be, but then they only show up for some Python versions... |
|
The tests are related, but I am away from dev machine at SciPy this week. I'll return to this next week. |
thomasjpfan
left a comment
There was a problem hiding this comment.
This PR looks like a fairly straight forward migration!
src/_image_wrapper.cpp
Outdated
| if (py_inverse == NULL) { | ||
| return NULL; | ||
| } | ||
| pybind11::ssize_t mesh_dims[2] = {dims[0]*dims[2], 2}; |
There was a problem hiding this comment.
Should this be dims[1]?
| pybind11::ssize_t mesh_dims[2] = {dims[0]*dims[2], 2}; | |
| pybind11::ssize_t mesh_dims[2] = {dims[0]*dims[1], 2}; |
| if (ndim < 2 || ndim > 3) | ||
| throw std::invalid_argument("Input array must be a 2D or 3D array"); | ||
|
|
||
| if (params.interpolation < 0 || params.interpolation >= _n_interpolation) { |
There was a problem hiding this comment.
Is this _n_interpolation check still required?
There was a problem hiding this comment.
That is a good question. The value is only ever used internally (between the Python and C++ code) and there is no way for a user to get this value as it is not part of the _interpd_ str to enum mapping.
On reflection, I think the correct approach is to remove it completely from the enum.
src/_image_wrapper.cpp
Outdated
| ¶ms.alpha, &convert_bool, ¶ms.norm, ¶ms.radius)) { | ||
| return NULL; | ||
| } | ||
| if (ndim < 2 || ndim > 3) |
There was a problem hiding this comment.
Very nit:
| if (ndim < 2 || ndim > 3) | |
| if (ndim != 2 || ndim != 3) |
So it's easier to connect the error message with the code.
There was a problem hiding this comment.
OK, but it would need to be ndim != 2 && ndim != 3.
| (type == NPY_INT16) ? resample<agg::gray16> : | ||
| (type == NPY_FLOAT32) ? resample<agg::gray32> : | ||
| (type == NPY_FLOAT64) ? resample<agg::gray64> : | ||
| (dtype.is(pybind11::dtype::of<std::uint8_t>())) ? resample<agg::gray8> : |
There was a problem hiding this comment.
At SciPy Conf 2023, I asked Henry (pybind11 maintainer) if there was a less verbose way to do this type of check and he said this was the best way.
|
It looks like pybind11 generates a function signature, so that could be removed from |
5469a8e to
5d90e48
Compare
Closes the fourth item of issue #23846.
This changes the
imagemodule to usepybind11rather than ourarray_viewclasses and direct use of the Python/C API. On my Linux dev machine this brings the_image*.solibrary down from 1.8 MB to 1.0 MB.I've taken the usual approach of the minimal set of changes to switch to
pybind11. This means that in some places we are still passing around pointers to array buffers an integer array dimensions. We could consider improving that in future, but it might be better to leave it as it is using the "if it ain't broke" principle.The standard approach to using
pybind11is to use thepynamespace, i.e.but I haven't done this as we already have a
pynamespace inpy_adapters.hand we can't keep both separate as importing some of the agg header files, as needed here, inevitably pulls inpy_adapters.h. When we have completed the transition topybind11we can change this.There are a number of utility functions in
py_converters.hand.cppwhich usePyObjectandvoidpointers. I have started apybind11equivalent of this inpy_converters_11.hand.cpp, and again when thepybind11transition is completed we can delete the old ones.With regard to code formatting, I have just done what I would do instinctively without thinking about it much and I am very happy to make changes if anyone has a strong opinion.