-
Notifications
You must be signed in to change notification settings - Fork 437
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
Fix memory leak in cython functions length and set_number_of_points #411
Conversation
Why does the vector need to be manually de-referenced? Is this a bug in cython? |
|
||
|
||
cdef void XDEC_vector_of_memview(Streamlines streamlines) nogil: | ||
# Cython automatically convert list of numpy array into vector of memoryviews but |
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.
Typos. Please rephrase: can convert a list of numpy array into a vector of memoryviews but ...
I'm worried that if/when the bug is fixed in cython we'll end up On Wed, Aug 27, 2014 at 11:31 AM, Eleftherios Garyfallidis <
|
It be nice if we could figure out a fix that would work with multiple Bago On Wed, Aug 27, 2014 at 11:40 AM, Eleftherios Garyfallidis <
|
Yes, the new method gives 90X speedups and the API is much better. On Wed, Aug 27, 2014 at 2:55 PM, MrBago notifications@github.com wrote:
|
Can I suggest that we re-write these functions using python lists instead On Wed, Aug 27, 2014 at 12:01 PM, Eleftherios Garyfallidis <
|
Since I apply the fix at the end of the function, it should not be a problem to decrease the refcount twice. I just tried it (adding many |
Also my benchmark results: python length_bench.py timing float32 On Wed, Aug 27, 2014 at 2:18 PM, Bago mrbago@gmail.com wrote:
|
Lists look nice, I'll have a closer look. |
@MrBago thanks, you made me realised we don't really need |
@@ -101,11 +93,14 @@ def length(streamlines): | |||
|
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'm a little worried that you're only checking the shape of the first array here. Could this lead to segfault if any of the other arrays do not have enough points? It seems like there is a pretty easy fix thought, if you just make _length
work for any number of points you will not have this issue, you can drop the TODO and you can take care of #412 at the same time (#412 is going to conflict with these changes so we might as well just take care of it here so we don't need to merge them).
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.
You are right if streamlines have different number of dimensions it will produce unexpected results. I generalized both _length
and _arclengths
and merge #412.
… to prevent the generated cpp code from calling pow (visual c gets confused because it doesnt know what version of pow to use) Conflicts: dipy/tracking/streamlinespeed.pyx
Now functions |
@MrBago this looks ready. Can you merge it? |
Gently reminder in case you forgot, is there anything missing for this PR? |
Fix memory leak in cython functions length and set_number_of_points
Hello @MarcCote, @MrBago, @Garyfallidis |
My mistake, I was not aware that resource was a Unix system module! https://docs.python.org/2/library/resource.html Now that we are not using c++ in Cython, (that is why we had leaks in the first place) we could remove the memory_leak test. See PR #416 |
I found a memory leak in the cythonized version of
dipy.tracking.streamline.length
anddipy.tracking.streamline.set_number_of_points
. Cython automatically convert a list of numpy arrays into a vector of memoryviews but at the end of the function, when clearing the vector, memviews' refcount are not decreased. So, I do it manually.I added a new unit test to expose the memory leak:
test_streamline:TestStreamline.test_memory_leak()
. Below, I report the difference in RAM usage between successive calls to each function.Before
length()
['0.13Mo', '0.22Mo', '0.28Mo', '0.50Mo', '0.31Mo', '0.33Mo', '0.08Mo', '0.41Mo', '0.14Mo', '0.06Mo', '0.47Mo', '0.31Mo', '0.32Mo', '0.17Mo', '0.48Mo', '0.29Mo', '0.06Mo', '0.13Mo', '0.20Mo']
set_number_of_points()
['1.50Mo', '0.90Mo', '1.26Mo', '1.11Mo', '1.89Mo', '1.06Mo', '1.02Mo', '1.09Mo', '1.12Mo', '1.17Mo', '1.12Mo', '1.12Mo', '1.12Mo', '1.12Mo', '1.12Mo', '1.12Mo', '1.12Mo', '0.98Mo', '1.09Mo']
Now
length()
['0.15Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo']
set_number_of_points()
['0.06Mo', '0.17Mo', '0.00Mo', '0.25Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo', '0.00Mo']