Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Tracker]: free-threaded Python support #28611

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

Open
1 task
andfoy opened this issue Jul 23, 2024 · 13 comments
Open
1 task

[Tracker]: free-threaded Python support #28611

andfoy opened this issue Jul 23, 2024 · 13 comments

Comments

@andfoy
Copy link
Contributor

andfoy commented Jul 23, 2024

This tracking issue aims to collect all the issues and PRs related for the upcoming free-threaded CPython 3.13 (a.k.a. "no-GIL") builds. Until now, as of #28610 all the test suite is passing (at least locally).

Right now, a complete triaging of all modules is required in order to detect any potential concurrency issues (C-thread safety issues), in order to either fix them or mark them as non-free-threaded compliant.

We invite the community and maintainers with extensive knowledge of the project to highlight the existence of any potential thread-safety issues that currently exist.

Here are some resources that might be useful in the context of free-threaded Python

Pull Requests

@QuLogic
Copy link
Member

QuLogic commented Jul 24, 2024

I've tested this before, and it runs fine, but there's not really much we could plausibly do until pybind11 supports free-threading.

@QuLogic
Copy link
Member

QuLogic commented Jul 24, 2024

Hmm, actually, I missed the fact that py::mod_gil_not_used was added in 2.13.0, so we can try setting that. However, kiwisolver doesn't set the flag yet, so we're still a bit stuck.

@tacaswell
Copy link
Member

I have run the test suite locally with PYTHON_GIL=0 and it seems to work.

@rgommers
Copy link

We're upgradingto pybind11>=2.13.1 in SciPy (PR open, not yet merged) and didn't have any issues with it.

However, kiwisolver doesn't set the flag yet, so we're still a bit stuck.

Since kiwisolver doesn't seem to have nightlies, it probably doesn't matter for progress here? It just has to be built from source in CI, and the PYTHON_GIL environment variable will override the lack of py::mod_gil_not_used usage.

@QuLogic
Copy link
Member

QuLogic commented Jul 24, 2024

I was having issues with contourpy, but it looks like that was an old cached wheel, as purging that and re-installing is working now.

@greglucas
Copy link
Contributor

I have put a PR into kiwisolver to add free threading support as well.
nucleic/kiwi#186

All of the other external dependencies looked like they already declared themselves ready for free threading support. So now I think we need to look at declaring our own internal modules as ready for free threading.

@QuLogic
Copy link
Member

QuLogic commented Sep 9, 2024

I can do that, but hope to have the pybind11 conversion in first, since that makes it (ever so slightly) easier.

@ngoldbaum
Copy link
Contributor

I just hit a case where matplotlib reenables the GIL at runtime:

<frozen importlib._bootstrap>:488: RuntimeWarning: The global interpreter lock (GIL) has been enabled to load module 'matplotlib.backends._macosx', which has not declared that it can run safely without the GIL. To override this behavior and keep the GIL disabled (at your own risk), run with PYTHON_GIL=0 or -Xgil=0.

I'm on a Mac so I guess it defaults to the MacOS backend, and the extension it uses doesn't declare free-threaded support.

No idea if that was left that way on purpose.

@greglucas
Copy link
Contributor

I'm on a Mac so I guess it defaults to the MacOS backend, and the extension it uses doesn't declare free-threaded support.

No idea if that was left that way on purpose.

I don't think so. I believe we probably just updated the pybind11 modules in #28819 and forgot to include the macos module. I know I tried it out on a mac before and had it working.

I believe this is the place that needs updating if you care to test it out and PR it?

#ifdef Py_GIL_DISABLED
    PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
#endif

@ngoldbaum
Copy link
Contributor

Thanks! I'll send in a PR.

I see you work at LASP - I spent a few years in a cubicle deep inside the lab on Colorado Ave doing undergrad research at CU! Small world :)

@ngoldbaum
Copy link
Contributor

So, all of these variables are definitely not thread-safe:

matplotlib/src/_macosx.m

Lines 28 to 44 in ede8dc4

/* Keep track of modifier key states for flagsChanged
to keep track of press vs release */
static bool lastCommand = false;
static bool lastControl = false;
static bool lastShift = false;
static bool lastOption = false;
static bool lastCapsLock = false;
/* Keep track of whether this specific key modifier was pressed or not */
static bool keyChangeCommand = false;
static bool keyChangeControl = false;
static bool keyChangeShift = false;
static bool keyChangeOption = false;
static bool keyChangeCapsLock = false;
/* Keep track of the current mouse up/down state for open/closed cursor hand */
static bool leftMouseGrabbing = false;
// Global variable to store the original SIGINT handler
static PyOS_sighandler_t originalSigintAction = NULL;

I bet if you tried to interact with any matplotlib windows on a mac from different python threads, bad things and/or weird things would happen.

But I guess keyboard and mouse state is probably effectively global state most of the time? So maybe it doesn't matter much and we can just document this somewhere?

The signal handler might be a more pernicious issue.

@greglucas
Copy link
Contributor

I see you work at LASP - I spent a few years in a cubicle deep inside the lab on Colorado Ave doing undergrad research at CU! Small world :)

👋 ironically, I am in a cube on Colorado Ave, but luckily have a window view of the ponds which is nice.

I bet if you tried to interact with any matplotlib windows on a mac from different python threads, bad things and/or weird things would happen.

Is there a way to test this? The interactive windows rely on the MacOS toolkits and window managers and are running in the OS' own multi-threaded context already.

But I guess keyboard and mouse state is probably effectively global state most of the time? So maybe it doesn't matter much and we can just document this somewhere?

We have this page: https://matplotlib.org/stable/users/explain/figure/interactive_guide.html#threading
which does state that in general it is not safe to draw from external threads. The suggestion is for users to do all of their processing/updating in background threads (taking into account their own thread races/issues) and then request a draw on the main event-loop thread, which we handle via draw_idle().

I think our stance has generally been to try and follow numpy's lead, we will declare support for the free-threading build and not poison the imports. But, we also likely won't be able to make everything threadsafe and users will need to think about locks on their end as well. Several of us have tried the free threading build and it did "work", but I don't think anyone has truly stress tested it.

@ngoldbaum
Copy link
Contributor

I think our stance has generally been to try and follow numpy's lead, we will declare support for the free-threading build and not poison the imports. But, we also likely won't be able to make everything threadsafe and users will need to think about locks on their end as well. Several of us have tried the free threading build and it did "work", but I don't think anyone has truly stress tested it.

Makes sense, I'll go ahead and send in a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants