-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Add CI to test scikit-image against free-threaded Python 3.13 #7463
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
Conversation
Thanks @andfoy, that's super helpful! |
Tests are now passing locally in my fork: https://github.com/andfoy/scikit-image/actions/runs/9900010082/job/27349985531 |
Thanks again, this looks good to me. Now, how do we shore up our test suite to actually create parallel faults if they are present? I suspect our current suite simply won't catch those. |
Well, the usual first step is to identify which classes or functions may have a shared state (usually a big culprit for concurrency issues). I did a similar exercise throughout However, this is a very time consuming exercise that should be conducted with planning ahead, i.e., first making sure that the most popular functionality of scikit-image is tested for concurrency first. I don't know how much budget we can spend here from the current Quansight labs project, maybe @rgommers knows more about how we can help the project to improve its parallelism support. |
Agreed. I'm not sure that there is much shared/global state - if there is, maintainers often know where it's located. In scikit-image I believe there's a lot of Cython and Pythran code, and no C/C++ code (right?). Pythran code is fairly constrained in how it can be written - I believe individual numerical kernels are safe. For Cython code that's written in C-like ways, it can have thread-safety issues. I suggest auditing it quickly for odd patterns. And maybe @stefanv can suggest a couple of the most heavily used and complex functions to write some new parallel tests for? That tends to be pretty quick to do, and if they all pass that gives a good amount of confidence (plus it's a test pattern that's then easy for future contributors to emulate). At that point I would stop unless scikit-image-specific bugs show up. I'm hoping that that won't be the case. Given the amount of Cython code and there being both known and unknown issues in Cython, I think it's perhaps more likely to hit Cython (or NumPy, or CPython) issues than problems in scikit-image itself. I'd also suggest opening a tracking issue to capture the plans/progress, that's easier to find that a merged PR. |
Co-authored-by: Stefan van der Walt <sjvdwalt@gmail.com>
Should we also publish a nightly wheel for packages that test against us? |
Thanks for guidance on testing! We do have parallel tests for some of our Cython code, and hopefully that catches the worst of it. All of our C++ code comes via Cython, but we do have some C code for phase unwrapping ( |
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.
Tentatively approved, with two (minor) questions.
skimage/util/_map_array.py
Outdated
@@ -129,7 +129,7 @@ def __len__(self): | |||
"""Return one more than the maximum label value being remapped.""" | |||
return np.max(self.in_values) + 1 | |||
|
|||
def __array__(self, dtype=None): | |||
def __array__(self, dtype=None, copy=False): |
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 function not only handle the copy=True
case?
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.
According to the documentation, it should be copy=None
, I've just updated it
r'\*\*(\w+)\*\* \:.*?\n(.*?)(?=\n [\*\S]+)', doc, flags=re.DOTALL | ||
) | ||
arg_regex = r'\*\*(\w+)\*\* \:.*?\n(.*?)(?=\n [\*\S]+)' | ||
if sys.version_info >= (3, 13): |
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.
What is this change for?
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.
After Python 3.13, the docstrings extracted via the __doc__
attribute now have their initial indentation offsets stripped. Thus this regex now needs to be modified in order for it to work without considering the initial indentation. See: https://docs.python.org/3.13/whatsnew/3.13.html#other-language-changes
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.
@andfoy, thanks for getting this process started!
How does Cython's |
I can open a follow up PR to upload free-threaded nightly wheels to the Scientific Python Anaconda distribution channel |
The xref numpy/numpy#26950 for the pattern to use the new |
We only have one source of C code:
If, in addition, we can guarantee that Cython and Pythran codes are safe, then I think we're good (I don't currently have enough knowledge to perform such a check). |
@stefanv, thanks for the references! After looking at them, they should not have any issues regarding C module registration, since they are being included as part of other Cython source. |
From my side, this PR is ready |
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.
Let's give it a shot!
# TODO: delete when scipy, numpy, cython and pywavelets free-threaded wheels are available on PyPi | ||
FREE_THREADED_BUILD="$(python -c"import sysconfig; print(bool(sysconfig.get_config_var('Py_GIL_DISABLED')))")" | ||
if [[ $FREE_THREADED_BUILD == "True" ]]; then | ||
pip install --pre -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple cython numpy scipy pywavelets |
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.
We should keep an eye on whether this actually provides pre-releases in our CI for FREE_THREADED_BUILD=True
. We've had issues with pip updating indirect dependencies despite the upgrade strategy being "only-if-needed".
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 otherwise provided the CI passes.
Two approvals and the one CI failure is unrelated. Can this PR be merged? |
That does seem like a good idea. In other projects we've done that as a next step after adding regular CI. And in NumPy we've now merged the default and free-threaded wheel builds; 2.1.0 should publish |
Thanks for helping us get this testing in! And sorry for the small stall at the end. It's easy to forget PRs when waiting on the CI. 🙈 |
Let me open a followup PR to upload nightly wheels |
Description
See #7464
This PR enables testing scikit-image against free-threaded Python, this is part of the ongoing effort to test projects against the changes proposed in PEP703
For more information see the following related PRs in other projects:
Checklist
./doc/examples
for new featuresRelease note
For maintainers and optionally contributors, please refer to the instructions on how to document this PR for the release notes.