1 #pragma once 2 3 #include <c10/macros/Export.h> 4 #include <c10/util/Exception.h> 5 6 /// This file provides some simple utilities for detecting common deadlocks in 7 /// PyTorch. For now, we focus exclusively on detecting Python GIL deadlocks, 8 /// as the GIL is a wide ranging lock that is taken out in many situations. 9 /// The basic strategy is before performing an operation that may block, you 10 /// can use TORCH_ASSERT_NO_GIL_WITHOUT_PYTHON_DEP() to assert that the GIL is 11 /// not held. This macro is to be used in contexts where no static dependency 12 /// on Python is available (we will handle indirecting a virtual call for you). 13 /// 14 /// If the GIL is held by a torchdeploy interpreter, we always report false. 15 /// If you are in a context where Python bindings are available, it's better 16 /// to directly assert on PyGILState_Check (as it avoids a vcall and also 17 /// works correctly with torchdeploy.) 18 19 #define TORCH_ASSERT_NO_GIL_WITHOUT_PYTHON_DEP() \ 20 TORCH_INTERNAL_ASSERT( \ 21 !c10::impl::check_python_gil(), \ 22 "Holding GIL before a blocking operation! Please release the GIL before blocking, or see https://github.com/pytorch/pytorch/issues/56297 for how to release the GIL for destructors of objects") 23 24 namespace c10::impl { 25 26 C10_API bool check_python_gil(); 27 28 struct C10_API PythonGILHooks { 29 virtual ~PythonGILHooks() = default; 30 // Returns true if we hold the GIL. If not linked against Python we 31 // always return false. 32 virtual bool check_python_gil() const = 0; 33 }; 34 35 C10_API void SetPythonGILHooks(PythonGILHooks* factory); 36 37 // DO NOT call this registerer from a torch deploy instance! You will clobber 38 // other registrations 39 struct C10_API PythonGILHooksRegisterer { PythonGILHooksRegistererPythonGILHooksRegisterer40 explicit PythonGILHooksRegisterer(PythonGILHooks* factory) { 41 SetPythonGILHooks(factory); 42 } ~PythonGILHooksRegistererPythonGILHooksRegisterer43 ~PythonGILHooksRegisterer() { 44 SetPythonGILHooks(nullptr); 45 } 46 }; 47 48 } // namespace c10::impl 49