-
-
Notifications
You must be signed in to change notification settings - Fork 600
Fix memory leak in conversion of symbolic expressions #40003
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
base: develop
Are you sure you want to change the base?
Conversation
Documentation preview for this PR (built with commit e7de1e3; changes) is ready! 🎉 |
In theory should be fine, but in practice I'd rather finding a more sane way to handle this e.g. by making lifetime ownership more explicit / following rule of 3/5/0 / etc. We're using C++ here, not C. |
Thank you very much for looking into this! So I have another fix which goes as follows: move the above
This has to be done in various places in This still fixes both bugs on my device, and all doctests run fine. But before pushing a commit, I want to make sure that this is the kind of fix you had in mind? (yes, you have unmasked me as a C user!) |
I… will need to look at the code and decide how best to encapsulate the lifetime. If you have to change every call sites, this is pretty much a breaking API change. P/s: I wonder how much we have diverged from ginac. There are issues like #38868 which is already fixed upstream. |
My conclusion:
I don't know why the difference exists. But I think the best option is to either
Side note: browsing through the occurrences of
here |
Just return a |
This seems to be a big issue actually. I feel that the code has not been much updated with upstream patches, and making the code up to date would be a major effort.
I have done it with the reference, thanks!
So I arrived to the same conclusion for the difference between the constructors of
Thanks for catching that one, I did take care of it as well! |
I suggest adding a comment to
|
Good idea! Done. |
I have looked into bug #27536.
When constants are converted, for instance when calling
RDF(pi)
, the method_eval_self
is called. In the process,Py_INCREF
is called twice innumeric::to_pyobject
(insrc/sage/symbolic/ginac/numeric.cpp
) andbasic & ex::construct_from_pyobject
(insrc/sage/symbolic/ginac/ex.cpp
).To avoid this, I propose to inline the code instead of calling it implicitly when returning. In the inlined code, of course, remove the
Py_INCREF
.Another leak was due to
PyDict_New
being called without a correspondingPy_DECREF
, this is also fixed.I have also noticed that some computations and memory usage were due to default overall coefficients being copied every time. I added another commit to return pointers to these coefficients instead.
It turns out this was the problem in #27185.
It seems to me that this fixes the problems mentioned in the bug tickets. But this is my first time pushing C++ code into production so there might be some mistakes.
I am not sure whether a
numeric
object keeps some memory after being deleted, but at least the Python objects do not remain, and this frees gigabytes of memory when running the codes in the tickets.Doctesting Sage runs fine on my device.
Fixes #27185.
Fixes #27536.
📝 Checklist