FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Use pybind11 in image module by ianthomas23 · Pull Request #26275 · matplotlib/matplotlib · GitHub

Repository navigation

Use pybind11 in image module - #26275

Merged
ksunden merged 6 commits into
matplotlib:mainfrom
ianthomas23:pybind11_image2
Sep 27, 2023
Merged

ksunden merged 6 commits into
matplotlib:mainfrom
ianthomas23:pybind11_image2

Conversation

Copy link
Copy Markdown
Member

Closes the fourth item of issue #23846.

This changes the image module to use pybind11 rather than our array_view classes and direct use of the Python/C API. On my Linux dev machine this brings the _image*.so library 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 pybind11 is to use the py namespace, i.e.

namespace py = pybind11;

but I haven't done this as we already have a py namespace in py_adapters.h and we can't keep both separate as importing some of the agg header files, as needed here, inevitably pulls in py_adapters.h. When we have completed the transition to pybind11 we can change this.

There are a number of utility functions in py_converters.h and .cpp which use PyObject and void pointers. I have started a pybind11 equivalent of this in py_converters_11.h and .cpp, and again when the pybind11 transition 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.

Comment thread src/_image_wrapper.cpp
(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> :

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

This is more verbose than it used to be, but is the recommended way of checking dtypes in pybind11.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

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.

ianthomas23 force-pushed the pybind11_image2 branch 2 times, most recently from 22a0788 to ce7afe1 Compare July 8, 2023 14:50
oscargus added this to the v3.8.0 milestone Jul 13, 2023

Copy link
Copy Markdown
Member

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...

Copy link
Copy Markdown
Member Author

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

This PR looks like a fairly straight forward migration!

Comment thread src/_image_wrapper.cpp Outdated
if (py_inverse == NULL) {
return NULL;
}
pybind11::ssize_t mesh_dims[2] = {dims[0]*dims[2], 2};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Should this be dims[1]?

Suggested change
pybind11::ssize_t mesh_dims[2] = {dims[0]*dims[2], 2};
pybind11::ssize_t mesh_dims[2] = {dims[0]*dims[1], 2};

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Yes it should.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Done.

Comment thread src/_image_wrapper.cpp
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) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Is this _n_interpolation check still required?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Done.

Comment thread src/_image_wrapper.cpp Outdated
&params.alpha, &convert_bool, &params.norm, &params.radius)) {
return NULL;
}
if (ndim < 2 || ndim > 3)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Very nit:

Suggested change
if (ndim < 2 || ndim > 3)
if (ndim != 2 || ndim != 3)

So it's easier to connect the error message with the code.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

OK, but it would need to be ndim != 2 && ndim != 3.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Done.

Comment thread src/_image_wrapper.cpp Outdated

thomasjpfan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

LGTM

Comment thread src/_image_wrapper.cpp
(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> :

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

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.

Comment thread src/_image_wrapper.cpp
ksunden modified the milestones: v3.8.0, v3.9.0 Aug 8, 2023
oscargus mentioned this pull request Mar 30, 2023
13 tasks done
Comment thread src/_image_wrapper.cpp Outdated
Comment thread src/_image_wrapper.cpp Outdated
Comment thread src/_image_wrapper.cpp Outdated
Comment thread src/_image_wrapper.cpp Outdated
Comment thread src/_image_wrapper.cpp Outdated
Comment thread src/_image_wrapper.cpp

QuLogic commented Sep 14, 2023

Copy link
Copy Markdown
Member

It looks like pybind11 generates a function signature, so that could be removed from image_resample__doc__.

Comment thread src/py_converters_11.cpp Outdated
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants


Back | FazBrowse Home | New Git URL