Skip to content
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

Update module setup code for free-threaded CPython #6137

Merged
merged 5 commits into from Apr 18, 2024

Conversation

lysnikolaou
Copy link
Contributor

Trying to build Cython (and run the test suite) with the latest CPython main with --disable-gil leads to segfaults. The following patch fixes the segfaults. Running the test suite with -X gil=1 (GIL enabled, default) succeeds locally on my machine, while running it with -X gil=0 (GIL disabled) fails with 8 test failures, all related to refnanny.

I'm opening this PR to see whether these changes really make sense (probably first time where there's two CYTHON_COMPILING_IN_* flags enabled) and I'll look into the failures as well, if that's okay. Also, NumPy builds under the free-threaded build with these changes.

Copy link
Contributor

@scoder scoder left a comment

Choose a reason for hiding this comment

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

We don't have a nogil-CPython test job, so we're currently running rather blind on this configuration.

#elif defined(Py_GIL_DISABLED) || defined(Py_NOGIL)
#elif defined(Py_NOGIL)
Copy link
Contributor

Choose a reason for hiding this comment

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

Now that the nogil fork is merged, it probably makes sense to treat it as a special case of CPython. The risky sections that we used to hide under the …IN_CPYTHON macro should long have received their own special macro (like USE_BORROWED_REFS etc.).

@lysnikolaou
Copy link
Contributor Author

We don't have a nogil-CPython test job, so we're currently running rather blind on this configuration.

Correct. I can work on adding CI for nogil-CPython if you want, but that will probably fail for a while. Also, setup-python currently does not support nogil (actions/setup-python#771), but there' a similar action we can use.

Comment on lines 339 to 343
#ifdef Py_GIL_DISABLED
#define CYTHON_COMPILING_IN_NOGIL 1
#else
#define CYTHON_COMPILING_IN_NOGIL 0
#endif
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a bit risky. Currently, there is only ever one CYTHON_COMPILING_IN… macro set to 1, which makes "if-elif-else" special cases easy to write and follow. I'd rather rename this to distinguish it from the "main" target environment (which continues to be CPython here).

OTOH, "compiling in" is pretty accurate, and seeing a name like CYTHON_IN_CPYTHON_NOGIL would make me wonder if someone just forgot the COMPILING part there.

Maybe CYTHON_COMPILING_IN_CPYTHON_NOGIL would be ok as a compromise? That would at least link it to the CPYTHON macro. I'll be happy to read better suggestions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

CYTHON_COMPILING_IN_CPYTHON_NOGIL sounds good to me.

Cython/Utility/ModuleSetupCode.c Outdated Show resolved Hide resolved
Cython/Utility/ModuleSetupCode.c Outdated Show resolved Hide resolved
Cython/Utility/ModuleSetupCode.c Outdated Show resolved Hide resolved
@ngoldbaum
Copy link
Contributor

When I compile cython itself on this branch, I see warnings like

  /Users/goldbaum/Documents/cython/Cython/Plex/DFA.c:7321:13: warning: code will never be executed [-Wunreachable-code]
   7321 |             goto bad;
        |             ^~~~~~~~
  /Users/goldbaum/Documents/cython/Cython/Plex/DFA.c:10197:79: warning: code will never be executed [-Wunreachable-code]
   10197 |         if (unlikely(__Pyx_PyTuple_SET_ITEM(varnames_tuple, i, varnames[i]))) goto done;
         |                                                                               ^~~~~~~~~
  2 warnings generated.

@da-woods
Copy link
Contributor

da-woods commented Apr 8, 2024

When I compile cython itself on this branch, I see warnings like

That probably is unrelated. The Limited API work introduces some error checking that's skipped for non-limited API operations. That'll add some unused paths on the non-limited API mode. At some point we're going to need to clean up the warnings from those.

Edit: unrelated

@da-woods
Copy link
Contributor

da-woods commented Apr 8, 2024

#elif defined(Py_GIL_DISABLED) || defined(Py_NOGIL)

A few months ago @colesbury asked to keep the old Py_GIL_DISABLED define because apparently some people are using his old prototype fork (#5852 (comment)).

My proposal would be to treat them as two unrelated products and have a separate define for each. So leave the old code as is (maybe renaming to CYTHON_COMPILING_IN_NOGIL_PROTOTYPE or something like that) and treat the new official free-threating CPython as @scoder suggests above.

@colesbury
Copy link
Contributor

colesbury commented Apr 8, 2024

FWIW, I think we can now drop the old Py_NOGIL support (i.e., nogil-3.9) and just include Py_GIL_DISABLED (i.e., upstream CPython 3.13 with the --disable-gil build configuration).

I think we should be able update scikit-learn's continuous build soon, and in the meantime I'm already maintaining out-of-tree patches and can continue to do so.

@da-woods
Copy link
Contributor

da-woods commented Apr 8, 2024

FWIW, I think we can now drop the old Py_NOGIL support (i.e., nogil-3.9) and just include Py_GIL_DISABLED (i.e., upstream CPython 3.13 with the --disable-gil build configuration).

Thanks - I'm happy for it to be dropped then.

@lysnikolaou
Copy link
Contributor Author

Regarding the CI job, it probably makes more sense to keep it in a separate fork, right? I assume it'll fail a lot over the next few weeks, and it probably wouldn't be a good idea to always have a red CI.

@scoder
Copy link
Contributor

scoder commented Apr 9, 2024

Regarding the CI job, it probably makes more sense to keep it in a separate fork, right? I assume it'll fail a lot over the next few weeks, and it probably wouldn't be a good idea to always have a red CI.

The Py3.13 jobs have allow_failures=true, and so would the nogil jobs. CPython's C-API has been under heavy changes for the last 2-3 releases, so we regularly end up with failing "latest Python" CI jobs for a while, until the problems either fix themselves (rarely) or we find the time to look into the failures and then either fix them on our side (sometimes) or start a discussion in their bug tracker (usually).

@ngoldbaum
Copy link
Contributor

Any further comments on this? Lysandros is on vacation for the next week or two but he's asked me to help make sure this gets merged.

Cython/Utility/ModuleSetupCode.c Outdated Show resolved Hide resolved
Cython/Utility/ModuleSetupCode.c Outdated Show resolved Hide resolved
Cython/Utility/ModuleSetupCode.c Outdated Show resolved Hide resolved
Cython/Utility/ModuleSetupCode.c Outdated Show resolved Hide resolved
Cython/Utility/ModuleSetupCode.c Outdated Show resolved Hide resolved
Cython/Utility/ModuleSetupCode.c Outdated Show resolved Hide resolved
@scoder scoder added this to the 3.1 milestone Apr 18, 2024
@scoder scoder merged commit 3ce5c8d into cython:master Apr 18, 2024
64 checks passed
@scoder
Copy link
Contributor

scoder commented Apr 18, 2024

Thanks

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.

None yet

5 participants