-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
ENH: Please support subinterpreters #24755
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
Comments
PEP 554 states:
The PEP also links to Isolating Extensions which has a lot of theory, but does not clearly state how to migrate a large existing c-extension library like NumPy to support subinterpreters. I think we would need to:
I am a bit unclear whether subinterpreters share a single GIL, if not we would also have to carefully examine the code for possible race conditions. This is a lot of work, and may have performance implications. What is your use case for subinterpreters? Do you think you could help with the effort or find funding for this effort? |
Relevant mailing list threads and issues: |
I suspect the vast majority of changes to be relatively easy, but there is still the same problem that we need someone to explicitly dedicate time on this, and I doubt it will be one of the current core devs. |
FWIW the recent CPython changes should be from PEP 684 “Per-Interpreter GIL”; PEP 554, for the Python API and subinterpreter management features, is still in draft status. |
There's a very strong use case for subinterpreters since PEP 684 for parallel processing that I expect would be useful to a lot of numpy client code: using subinterpreters in separate threads will enable shared memory (at least in a read-only case) with significantly less hassle than multiprocessing. |
I’m also very excited about the potential opportunities of using subinterpreters with numpy, and agree with what @mdekstrand said. In particular, the latest draft of PEP 734 discusses sharing data via the buffer protocol (and already implemented in the private interpreters module since 3.13a1). Since ndarrays can export their buffer or be created from one without copies, this could be a very nice pattern:
You get concurrency with performant, opt-in data sharing, without the hassles of managing subprocesses and using multiprocessing.shared_memory where you have to create a shared buffer of fixed size ahead of time and only create arrays using that. With interpreters you can take any random array you got and easily share it. |
InterpreterPoolExecutor's are to be introduced in 3.14 124548. At present, numpy imports fail due to "ImportError: module numpy._core._multiarray_umath does not support loading in subinterpreters": See following example: TPE and PPE work, IPE does not. from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import ProcessPoolExecutor
from interpreters_backport.concurrent.futures.interpreter import InterpreterPoolExecutor
def try_tpe():
with ThreadPoolExecutor() as executor:
executor.submit(exec, "import numpy as np;print('TPE:', np.random.rand(2))")
def try_ppe():
with ProcessPoolExecutor() as executor:
executor.submit(exec, "import numpy as np;print('PPE:', np.random.rand(2))")
def try_ipe():
with InterpreterPoolExecutor() as executor:
f = executor.submit(exec, "import numpy as np;print('IPE:', np.random.rand(2))")
f.result()
if __name__ == "__main__":
try_tpe()
try_ppe()
try_ipe() Footnote: I noted this recent comment, which perhaps closed the door on hope here; #27192 (comment) |
It's a sad thing that even the possibilities are closed. Now Python is heading towards true multithreaded parallelism with |
They aren't closed. A lot of work has happened (and is still happening) to supported free-threaded CPython over the past 6 months. Pretty much all that work is also directly relevant to support for subinterpreters. The extra work needed for subinterpreters - primarily moving to heap types I believe - will need someone to dig in and do that work though. None of the active maintainers are working on this, however contributions are very much welcome. |
The list of tasks is still this, although the documentation has gotten better:
|
@mattip I imagine cython support for subinterpreters would also be required? cython/cython#6445 |
Yes, that is part of the "carefully analyze code for other possible shared state". Cython does support the constructs needed for generating code compatible with subinterpreters, the question is more "are we using unsafe coding practices in our cython code?" Another area that will need adaptation is the f2py generated wrappers. |
Proposed new feature or change:
Version 1.25.1, Python 3.12.re02
After enabling interpreters in Python C Api:
PyInterpreterConfig config = {
.check_multi_interp_extensions = 1,
.gil = PyInterpreterConfig_OWN_GIL,
};
PyThreadState *tstate = NULL;
PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config);
if (PyStatus_Exception(status)) {
return -1;
}
Import numpy throws an exception:
module numpy.core._multiarray._umath does not support loading in subinterpreters
The text was updated successfully, but these errors were encountered: