Skip to content

Commit bdec157

Browse files
pytorchbotmalfet
andauthored
Fix profiler on cpython-3.13 (pytorch#154037)
Fix profiler on cpython-3.13 (pytorch#153848) Per [PEP 667](https://peps.python.org/pep-0667/) `PyFrame_GetLocals` no longer returns dict, but rather instance of `PyFrameLocalsProxy_Type`, so calling `PyDict_GetItemString` is no longer valid(it will always return None) and must be replaced with `PyMapping_GetItemString` Tested by partially reverting pytorch#141674 full revert will be done in the followup PR Fixes pytorch#148273 Pull Request resolved: pytorch#153848 Approved by: https://github.com/Skylion007 (cherry picked from commit c0343b1) Co-authored-by: Nikita Shulga <[email protected]>
1 parent a159920 commit bdec157

File tree

2 files changed

+11
-2
lines changed

2 files changed

+11
-2
lines changed

test/profiler/test_profiler.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,6 @@ def custom_layer(input_ten):
226226
q.backward()
227227

228228

229-
@unittest.skipIf(sys.version_info >= (3, 13), "segfaults")
230229
@instantiate_parametrized_tests
231230
class TestProfiler(TestCase):
232231
@unittest.skipIf(
@@ -2308,7 +2307,6 @@ def __init__(self, name, children) -> None:
23082307
self.children = [MockNode(name, i) for name, i in children.items()]
23092308

23102309

2311-
@unittest.skipIf(sys.version_info >= (3, 13), "segfaults")
23122310
class TestExperimentalUtils(TestCase):
23132311
def make_tree(self) -> list[MockNode]:
23142312
tree = {

torch/csrc/autograd/profiler_python.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,15 +862,26 @@ void PythonTracer::recordPyCall(
862862
// `PyFrame_FastToLocals` which forces the interpreter to materialize
863863
// the full dict of locals.
864864
auto locals = THPObjectPtr(PyFrame_GetLocals(frame));
865+
866+
#if PY_MAJOR_VERSION < 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 13)
865867
auto self = THPObjectPtr(PyDict_GetItemString(locals, "self"));
868+
#else
869+
// In Python-3.13+ `PyFrame_GetLocals()` returns instance of
870+
// PyFrameLocalsProxy_Type See PEP 667 for more info
871+
auto self = THPObjectPtr(PyMapping_GetItemString(locals, "self"));
872+
#endif
866873
Py_INCREF(self.get());
867874
auto back = THPFrameObjectPtr(PyFrame_GetBack(frame));
868875
TORCH_INTERNAL_ASSERT(back != nullptr);
869876
return tls.intern<CallType::PyModuleCall, E>(
870877
frame, self.get(), back.get());
871878
} else if (code.get() == optimizer_hook_) {
872879
auto locals = THPObjectPtr(PyFrame_GetLocals(frame));
880+
#if PY_MAJOR_VERSION < 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 13)
873881
auto self = THPObjectPtr(PyDict_GetItemString(locals, "self"));
882+
#else
883+
auto self = THPObjectPtr(PyMapping_GetItemString(locals, "self"));
884+
#endif
874885
Py_INCREF(self.get());
875886
auto back = THPFrameObjectPtr(PyFrame_GetBack(frame));
876887
TORCH_INTERNAL_ASSERT(back != nullptr);

0 commit comments

Comments
 (0)