-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make use of CPython limited API #94
Conversation
@astrofrog - there definitely wasn't put much thought in this, so I think we can indeed change it. It is done inside a ufunc, which means the GIL is released, so given the comment in https://github.com/numpy/numpy/blob/8d61ebc25a117337d148f1e3d96066653bd6419a/numpy/core/include/numpy/ndarraytypes.h#L359-L368, I don't think we can use the non-raw |
setup.cfg
Outdated
@@ -56,3 +56,6 @@ max-line-length = 100 | |||
|
|||
[pycodestyle] | |||
max-line-length = 100 | |||
|
|||
[bdist_wheel] | |||
py_limited_api = cp37 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I bumped Python minversion to 3.9 in #107 , so this needs updating. FYI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
dd30e9a
to
978feef
Compare
Switching to using malloc() seems to fix things - after a couple of other fixes this seems to work. Note that I've also simplified the wheel building config to not split up the different Python versions into separate builds. When using the limited API, cibuildwheel will first build e.g. the Python 3.9 wheel and then just test it on 3.10, 3.11 and 3.12 (but not build it again each time). But note that for now Python 3.12 probably won't work because of Numpy. So I have disabled Python 3.12 in the cibuildwheel config - however note that this doesn't actually matter as much as before because we only build wheels on Python 3.9 anyway - 3.10, 3.11 and 3.12 is just for testing. |
Well this seems like it could actually be ready (modulo review). The TL;DR is that this enables use of the limited CPython API which means that we can just build a wheel with the oldest supported version of CPython and it will then work with any future Python 3.x version. This is recognized by cibuildwheel which will just build the wheel for Python 3.9 and then test it on 3.9, 3.10, 3.11, etc. The benefits are:
For now Python 3.12 testing of the wheels is disabled but we can just enable it once there are stable releases of Numpy that work on Python 3.12 (but we don't need to hold back this PR until then) |
@@ -113,7 +113,7 @@ jobs: | |||
python -m venv --system-site-packages tests | |||
source tests/bin/activate | |||
python -m pip install --editable .[test] | |||
(nm -u erfa/ufunc.cpython-*.so | grep eraA2af) || exit 1 | |||
(nm -u erfa/ufunc.*.so | grep eraA2af) || exit 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The so files are now called ufunc.abi3.so hence the change
.github/workflows/ci_workflows.yml
Outdated
# Required so that cp312 can grab a pre-release numpy. | ||
# Can remove when cp312 is released. | ||
env: | | ||
CIBW_ENVIRONMENT: PIP_PRE=1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't grok the internals of erfa, so I cannot review but I wonder why you remove the extra job for py312. I split it out on purpose because py312 needs pre-release of numpy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #94 (comment) - with the limited API we don't build Python 3.12 wheels anymore. We just build 3.9 wheels and test them on 3.10+. Testing them on 3.12 is disabled for now because we can't have Python 3.12 as a separate job anymore with this PR.
If you would be more comfortable waiting for a Python 3.12 release of Numpy we can do that, but it's not strictly needed - if we know via other CI config that Python 3.12 works fine then testing the wheels on 3.9, 3.10 and 3.11 is probably sufficient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... What about using artifact upload/download for the py312? Though maybe numpy will ship py312 wheel anyway when 1.26 is released, so maybe we can just wait it out. Thanks for the clarification!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to just wait for 1.26 final, no point overcomplicating things.
For anyone coming to this now, see my latest summary of changes in #94 (comment) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me but one question and one request for a comment in the code.
I agree that we should wait until py312 compatible numpy is available.
Note that following a comment by @mhvk I've pushed a temporary commit to see what fails if I remove the typestruct workaround. |
7db3702
to
6b3b642
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Thanks @astrofrog |
@astrofrog - I think this is OK to merge once the numpy/python 3.12 issue is sorted! Thanks! |
@mhvk @avalentino @pllim - I just realized there is an easy way to request pre-releases on Python 3.12 similar to what @pllim was doing before without having to split up the build matrix so have pushed a commit here (da319b5). The wheels are now tested on Python 3.12. I believe this is therefore ready to merge assuming the CI passes. |
pyproject.toml
Outdated
|
||
[[tool.cibuildwheel.overrides]] | ||
select = "cp312-*" | ||
environment = "PIP_PRE=1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean all the wheels now use numpy 1.26rc or just cp312?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes on 3.12 the wheels are tested against the numpy RC. Note that we don't build any Python 3.12 wheels so the build dependencies are not important there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤪
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p.s. Are you going to do a similar patch for astropy
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha unfortunately not, Cython's support for the limited API is very rudimentary
Ah I need to add a tweak for win32, will do shortly |
numpy is going to push out wheel for win32 "soon", if you can wait a bit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
numpy 1.26 stable is out with py312 wheels. I think this can be simplified now.
da319b5
to
0595682
Compare
Workaround removed - this should be ready if the CI passes |
@mhvk @avalentino are you happy for this to be merged now? |
yes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A question whether we still need to skip python 3.12, just to be sure. If it is needed, do we need an issue to remind us to remove it?
Otherwise, a very nice simplification in our wheel building, for a single, simple change. Great! Ready to (squash&) merge!
pyproject.toml
Outdated
@@ -11,3 +11,6 @@ requires = [ | |||
"numpy>=1.26.0b1; python_version>='3.12'" | |||
] | |||
build-backend = 'setuptools.build_meta' | |||
|
|||
[tool.cibuildwheel] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need this now that numpy 1.26 is out?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops no will remove
pyproject.toml
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need a rebase to pick up my merged changes to this file.
0595682
to
844a5dc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, let's get it in! Thanks, @astrofrog!
Does switching to the limited API imply anything for performance? |
It shouldn't as the code is virtually unchanged (the one function that was changed was an alias to malloc anyway). But if anyone finds a performance degradation let me know! |
Doesn't this also limit what code Cython can produce? |
Ah, sorry, this doesn't use cython, nevermind then |
Belated LGTM. Thanks! |
This is meant to be an experiment in trying to see if we can use the Limited API - doing so would mean we would only need to build one wheel for each platform (rather than one per Python version and per platform). Note that this wouldn't require any changes to the wheel building machinery as cibuildwheel recognizes this and will only build one wheel and test it on all Python versions.
I am running into the issue that
PyArray_malloc
is an alias ofPyMem_RawMalloc
which isn't in the Limited API. I was wondering if there is a way we can allocate the arrays that would be compatible with the Limited API, for example usingPyMem_malloc
ormalloc
?@mhvk - as a Numpy expert, do you have any ideas?