mirror of
https://github.com/pytorch/pytorch.git
synced 2025-10-21 05:34:18 +08:00
Fix autograd thread crash with python-3.9 (#50998)
Summary: Update pybind repo to include `gil_scoped_acquire::disarm()` methods In python_engine allocate scoped_acquire as unique_ptr and leak it if engine is finalizing for Python-3.9+ Fixes https://github.com/pytorch/pytorch/issues/50014 and https://github.com/pytorch/pytorch/issues/50893 Pull Request resolved: https://github.com/pytorch/pytorch/pull/50998 Reviewed By: ezyang Differential Revision: D26038314 Pulled By: malfet fbshipit-source-id: 035411e22825e8fdcf1348fed36da0bc33e16f60
This commit is contained in:
committed by
Facebook GitHub Bot
parent
069602e028
commit
6f3aa58d80
@ -48,6 +48,10 @@ Engine& PythonEngine::get_python_engine() {
|
||||
return engine;
|
||||
}
|
||||
|
||||
#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 9
|
||||
#define IS_PYTHON_3_9_PLUS
|
||||
#endif
|
||||
|
||||
void PythonEngine::thread_init(int device, const std::shared_ptr<ReadyQueue>& ready_queue, bool should_increment) {
|
||||
// Increment thread usage count before acquiring the GIL
|
||||
if (should_increment) {
|
||||
@ -56,7 +60,11 @@ void PythonEngine::thread_init(int device, const std::shared_ptr<ReadyQueue>& re
|
||||
// Create a PyThreadState, but release the GIL. This lets pybind11::gil_scoped_acquire calls
|
||||
// inside thread_main acquire the GIL without having to create a new
|
||||
// PyThreadState each time.
|
||||
#ifdef IS_PYTHON_3_9_PLUS
|
||||
auto gil = std::make_unique<pybind11::gil_scoped_acquire>();
|
||||
#else
|
||||
pybind11::gil_scoped_acquire gil;
|
||||
#endif
|
||||
pybind11::gil_scoped_release no_gil;
|
||||
Engine::thread_init(device, ready_queue, false);
|
||||
|
||||
@ -64,6 +72,15 @@ void PythonEngine::thread_init(int device, const std::shared_ptr<ReadyQueue>& re
|
||||
// Decrement the count during shutdown if we incremented earlier.
|
||||
decrement_non_reentrant_thread_count();
|
||||
}
|
||||
|
||||
#ifdef IS_PYTHON_3_9_PLUS
|
||||
// Do not call PyEval_RestoreThread, PyThreadState_[Clear|DeleteCurrent] if runtime is finalizing
|
||||
if (_Py_IsFinalizing()) {
|
||||
no_gil.disarm();
|
||||
// TODO: call disarm rather than leak gil_scoped_acquired once PyThreadState_Clear can safely be called from finalize
|
||||
gil.release();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void PythonEngine::thread_on_exception(
|
||||
|
Reference in New Issue
Block a user