-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PyROOT] Fix memory leak in TTree __getattr__
pythonization
#15608
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you so much for such a quick fix! I wonder what was the root cause of the memory leak, maybe the CPyCppyy::Instance_FromVoidPtr
? Usually one possible culprit is excessive calls to the interpreter but I don't see any evident one in the modified code. Could you add some comment about this in the commit message?
void * finalAddress = nullptr; | ||
std::string finalType; | ||
std::tie(finalAddress, finalType) = ResolveBranch(tree, name, branch); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void * finalAddress = nullptr; | |
std::string finalType; | |
std::tie(finalAddress, finalType) = ResolveBranch(tree, name, branch); | |
const auto [finalAddress, finalType] = ResolveBranch(tree, name, branch); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that's an improvement because it hides the types. It's nice to know when reading that it's void *
and std::string
, no? I'll try to replace the auto
in your suggestion with something typed, if it's not too long
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, it's only working with auto
. I'll change the variable names to make the type clearer then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's just a suggestion, I see your point and you can leave it as it is if you find it not necessary 👍
PyObject *GetAttr(PyObject *self, PyObject *pyname) | ||
// Returns a Python tuple where the first element is either the desired | ||
// CPyCppyy proxy, or an address that still needs to be wrapped by the caller | ||
// in a proxy using cppyy.ll.cast. In the latter laster, the second tuple |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am unsure about this, but maybe you meant
// in a proxy using cppyy.ll.cast. In the latter laster, the second tuple | |
// in a proxy using cppyy.ll.cast. In the latter case, the second tuple |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thoughts were out-of-sync with the typing 🙂
Test Results 12 files 12 suites 2d 18h 50m 41s ⏱️ Results for commit 3f1ed33. ♻️ This comment has been updated with latest results. |
Thanks for the review! I have added something about the CPyCppyy API to the commit description and PR description as you requested:
|
By the way, I was so sure it would fail on Windows 32 bit! I think it's the first time I changed something with pointers in PyROOT and the CI was green first try 😆 So this time, there is for sure no "overfitting" to the tested platforms |
As reported on the forum: https://root-forum.cern.ch/t/memory-leak-in-pyroot-when-using-user-defined-c-macros-from-python-and-ttree-friends/59432 I fixed the memory leak in the Pythonization is in the usual way how I fix problems with the PyROOT CPython extension: re-implementing the offending parts in C++ and hoping that the problem is gone. Which it is! Note that the code also had no obvious memory leak before. where it was using the `CPyCppyy::Instance_FromVoidPtr` function from the CPyCppyy API. If similar problems appear, this function might have to be investigated in more detail. But for this commit it is not relevant: moving more Pythonization logic into the Python layer is better anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Can you apply the clang-format suggestions before merging?
I agree with @vepadulano . Then we should backport to 6.32. |
The ROOT code formatting style was almost respected already, and it would be better to do so consistently.
I only formatted the code as requested, so no need to wait for the CI. |
Fixes #15610
As reported on the forum:
https://root-forum.cern.ch/t/memory-leak-in-pyroot-when-using-user-defined-c-macros-from-python-and-ttree-friends/59432
According to that post, the problem is present at least since 6.26/04, but I suspect it has been there forever (at least 6.22 with with cppyy upgrade in 2019).
I fixed the memory leak in the Pythonization is in the usual way how I fix problems with the PyROOT CPython extension: re-implementing the offending parts in Python and hoping that the problem is gone. Which it is!
Note that the code also had no obvious memory leak before. where it was
using the
CPyCppyy::Instance_FromVoidPtr
function from the CPyCppyyAPI. If similar problems appear, this function might have to be
investigated in more detail.
But for this commit it is not relevant: moving more Pythonization logic
into the Python layer is better anyway.
The problem can be reproduced with a variation of the forum reproducer:
Output without this PR:
Output with this PR:
The time measurements exclude the toy data generation. The new implementation is also almost twice as fast as the old one, so a win-win!
Note: I''m pretty sure there was also a JIRA issue about this problem, I can't find it anymore...Edit: no, the issue I had in mind was not really the same: https://its.cern.ch/jira/browse/ROOT-9875.