DeadlockDetection.h 1.9 KB

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