[dynamo] better way to skip tracing sys.monitoring callables (#159369)

Better approach to https://github.com/pytorch/pytorch/pull/158171, according to https://github.com/python/cpython/issues/137178#issuecomment-3131617493.

Pull Request resolved: https://github.com/pytorch/pytorch/pull/159369
Approved by: https://github.com/Skylion007
This commit is contained in:
William Wen 2025-07-29 07:34:17 -07:00 committed by PyTorch MergeBot
parent 2176d481c1
commit 477c2273e1
3 changed files with 7 additions and 34 deletions

View File

@ -34,14 +34,6 @@ void eval_frame_callback_set(PyObject* obj) {
PyThread_tss_set(&eval_frame_callback_key, obj);
}
#if IS_PYTHON_3_12_PLUS
const size_t sys_monitoring_num_callables =
sizeof((PyInterpreterState){0}.monitoring_callables) / sizeof(PyObject*);
PyObject** get_monitoring_callables(PyInterpreterState* interp) {
return (PyObject**)interp->monitoring_callables;
}
#endif
// 3.14 Not supported at all. See cpython_defs.c for hints
#if !(IS_PYTHON_3_14_PLUS)
@ -590,23 +582,6 @@ static PyObject* set_eval_frame_py(PyObject* module, PyObject* callback) {
"python enabled=%d and is run_only=%d",
callback != Py_None,
callback == Py_False);
#if IS_PYTHON_3_12_PLUS
// skip tracing sys.monitoring callables
if (callback != Py_None && callback != Py_False) {
PyInterpreterState* interp = PyThreadState_GET()->interp;
PyObject** monitoring_callables_flat =
(PyObject**)interp->monitoring_callables;
for (size_t i = 0; i < sys_monitoring_num_callables; ++i) {
PyObject* callable = monitoring_callables_flat[i];
if (callable != NULL && PyFunction_Check(callable)) {
PyFunctionObject* func = (PyFunctionObject*)callable;
if (func->func_code != NULL) {
skip_code_recursive((PyCodeObject*)func->func_code);
}
}
}
}
#endif
return set_eval_frame(callback, PyThreadState_GET(), module);
}

View File

@ -11,11 +11,6 @@ PyObject* torch_c_dynamo_eval_frame_init(void);
#endif
#if IS_PYTHON_3_12_PLUS
extern const size_t sys_monitoring_num_callables;
PyObject** get_monitoring_callables(PyInterpreterState* interp);
#endif
// All the eval APIs change in 3.11 so we need to decide which one to use on the
// fly https://docs.python.org/3/c-api/init.html#c._PyFrameEvalFunction
#if IS_PYTHON_3_11_PLUS

View File

@ -7,10 +7,6 @@
#include <torch/csrc/dynamo/framelocals_mapping.h>
#include <torch/csrc/utils/python_compat.h>
#include <cstring>
#include <unordered_map>
#include <vector>
extern "C" {
extern PyObject* guard_complete_hook;
}
@ -143,6 +139,13 @@ PyObject* dynamo__custom_eval_frame(
auto fail = [&]() { clear_old_frame_if_python_312_plus(tstate, frame); };
#if IS_PYTHON_3_12_PLUS
if (tstate->tracing > 0) {
eval_default();
return eval_result;
}
#endif
ExtraState* extra = get_extra_state(F_CODE(frame));
if (callback.is(py::bool_(false)) && extra == nullptr) {