<div dir="ltr">Hey guys,<div><br></div><div>Please let me take a look at this before merging it. I have already done similar things. In fact, this is not needed for Python. I already have this working in ParaView's Python using observers and the fact that a Python observer holds on to the function object, which though a closure can hold a reference to the array. This works as long as Python is finalized after the VTK array is deleted.</div>

<div><br></div><div>Also, I am a little confused about why this is needed for Fortran arrays. Why couldn't you set VTK to not delete the array and leave it to the owner of the array to take care of deletion? My opinion is that passing ownership of an array allocated in a different code to VTK is usually a dangerous thing - the developers of the other code can easily add a deallocation method somewhere without noticing that VTK owns it. They are usually not aware of what VTK does, specially in in situ type application.</div>

<div><br></div><div>Best,</div><div>-berk</div><div><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jan 22, 2014 at 6:00 PM, Burlen Loring <span dir="ltr"><<a href="mailto:burlen.loring@gmail.com" target="_blank">burlen.loring@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Guys,<br>
<br>
I've refactored the patch as David suggested adding vtkCommand::PointerFreeEvent which is fired when the pointer passed to SetArray is no longer needed and the delete method is VTK_DATA_ARRAY_CALLBACK. Would you mind taking another look at it?<br>


<a href="http://review.source.kitware.com/#/c/14072/5" target="_blank">http://review.source.kitware.<u></u>com/#/c/14072/5</a><div class="im HOEnZb"><br>
<br>
Burlen<br>
<br>
On 01/19/2014 03:43 PM, David Gobbi wrote:<br>
</div><div class="HOEnZb"><div class="h5"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I meant vtkCommand, not vtkCallback.  Invoke a FreeEvent and catch it<br>
on the other side with a vtkCommand.<br>
<br>
On Sun, Jan 19, 2014 at 4:41 PM, David Gobbi <<a href="mailto:david.gobbi@gmail.com" target="_blank">david.gobbi@gmail.com</a>> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi Burlen,<br>
<br>
If that trick won't work, then maybe the easiest thing is to make the<br>
vtkDataArray generate a specific event (e.g. create a new event called<br>
a FreeEvent) that is called when the memory is freed.  That way you<br>
are taking advantage of the existing vtkCallback support, which is<br>
already wrapped by all of the wrapper languages.<br>
<br>
   David<br>
<br>
On Sun, Jan 19, 2014 at 4:22 PM, Burlen Loring <<a href="mailto:burlen.loring@gmail.com" target="_blank">burlen.loring@gmail.com</a>> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
thanks, that's a neat trick!<br>
<br>
it certainly keeps one safe : the numpy object is around while the array is.<br>
I don't think that this will do the right thing if the vtk array is resized,<br>
or if SetVoidPointer is called again. In both cases, the vtk data array is<br>
still alive and well, but the numpy array's ref count should be decremented.<br>
<br>
a python only solution wont work for me here, because I'm working in the<br>
C/C++ "glue layer" sitting in between the python app(s) (which aren't mine)<br>
and a legacy VTK based app. VTK objects aren't used in the app's python API<br>
at all,  only lists, tuples, and I'm adding support for numpy arrays. Using<br>
VTK objects in the API is not an option.<br>
<br>
<br>
On 1/19/2014 8:43 AM, David Gobbi wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi Burlen,<br>
<br>
There might be a simpler way to get VTK to free the numpy array,<br>
that won't require any changes to the VTK code at all: just add<br>
the numpy array to the VTK array as an attribute.  Here is some<br>
example code:<br>
<br>
== BEGIN EXAMPLE ==<br>
<br>
# An example of using numpy arrays in VTK<br>
import vtk<br>
import numpy<br>
import weakref<br>
import gc<br>
<br>
# Use a numpy array as a VTK array<br>
z = numpy.arange(0,10,1,float)<br>
a = vtk.vtkDoubleArray()<br>
a.SetVoidArray(z,10,1)<br>
<br>
# Make the VTK array track the numpy array<br>
a.array = z<br>
<br>
# Create weakrefs to check for deletion<br>
rz = weakref.ref(z)<br>
ra = weakref.ref(a)<br>
<br>
# Decref the numpy array, it won't be deleted yet<br>
del z<br>
gc.collect()<br>
if rz() == None:<br>
      print "numpy array is deleted (#1)"<br>
<br>
# Decref the VTK array, numpy array will be decref'd<br>
del a<br>
gc.collect()<br>
if rz() == None:<br>
      print "numpy array is deleted (#2)"<br>
<br>
== END EXAMPLE ==<br>
<br>
This works because the attributes of a VTK-Python object are kept<br>
alive for as long as the corresponding VTK-C++ object exists.<br>
<br>
    David<br>
<br>
On Sun, Jan 19, 2014 at 12:09 AM, Burlen Loring <<a href="mailto:burlen.loring@gmail.com" target="_blank">burlen.loring@gmail.com</a>><br>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
To illustrate the callback in action I wrote an example where data is<br>
transferred to VTK from numpy ndarrays. I hope this will help. README<br>
file<br>
explains the example. <a href="https://github.com/burlen/TestZeroCopyPython" target="_blank">https://github.com/burlen/<u></u>TestZeroCopyPython</a><br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
OK. as fas as VTK is concerned callbackData is intended to be a key<br>
for use by the callback, and VTK does nothing with it beyond passing<br>
it to the callback. I'll add a note about this to clarify.<br>
</blockquote>
Thanks. The problem with callback context ownership is that if it's a<br>
one-time, the callback "owns" the context, but if it's a notification<br>
kind of thing, the *notifier* owns the context (since the callback may<br>
never be called) and needs an additional function to free the context.<br>
<br>
</blockquote>
I'm not following your complaint here. We're concerned about a pointer to<br>
some array that must be kept alive while VTK uses it but must be released<br>
when VTK is done. In this situation VTK "no longer needs the data" only<br>
ever<br>
once. and just as VTK always will call free when the pointer is passed in<br>
through the existing SetArray w/ VTK_DATA_ARRAY_FREE flag. VTK will<br>
always<br>
call the callback, either when the vtkDataArray is resized or when it is<br>
Delete'd. The callback and callback data are pointers, as far as VTK is<br>
concerned they're just values, and VTK need not worry about free'ing<br>
them.<br>
Note that this doesn't prevent one from passing an instance of an<br>
arbitrary<br>
class in callbackData. In that case the instance should be deleted in the<br>
callback.<br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Works for me, although I'm not sure NULL callbackData is ever<br>
valid/usefull.<br>
</blockquote>
As an example, if you have a LocalFree or whatever on Windows, you just<br>
need the array parameter, so NULL callbackData is needed.<br>
</blockquote>
NULL callbackData would generally not work out. the callback needs<br>
non-NULL<br>
callbackData passed to it in order to identify the memory to free. In<br>
your<br>
example callbackData is the array pointer itself, not NULL. This is not a<br>
problem.<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
    Where array<br>
and callbackData might be needed is something like where you need the<br>
array, but callbackData is the arena to free it from. Currently, you<br>
only get one or the other.<br>
</blockquote>
actually I think currently you could get both without issue. don't forget<br>
callbackData is very flexible, it can be (point to) anything. In the case<br>
you're describing: write a class containing the arena and the array. pass<br>
a<br>
heap allocated instance of your class as callbackData when you call<br>
SetArray. When VTK calls the callback, in addition to releasing the array<br>
data, delete the instance to your class.<br>
<br>
Would you be happier with a polymorphic reference counted functor, rather<br>
than a callback? Initially I thought this would be overkill, but I'd be<br>
willing to go that way if people are against the callback idea.<br>
<br>
Burlen<br>
<br>
<br>
On 01/17/2014 09:19 PM, Ben Boeckel wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On Fri, Jan 17, 2014 at 15:21:42 -0800, Burlen Loring wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Yes, my intention is that for now they'd be used from glue code<br>
rather than exposed directly. In the future the API could be exposed<br>
in the wrapped languages if there were a compelling use case for it.<br>
Until then it's not worth the effort since I doubt VTK wrapping codes<br>
would handle it correctly.<br>
</blockquote>
That's valid; just making sure :) .<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
OK. as fas as VTK is concerned callbackData is intended to be a key<br>
for use by the callback, and VTK does nothing with it beyond passing<br>
it to the callback. I'll add a note about this to clarify.<br>
</blockquote>
Thanks. The problem with callback context ownership is that if it's a<br>
one-time, the callback "owns" the context, but if it's a notification<br>
kind of thing, the *notifier* owns the context (since the callback may<br>
never be called) and needs an additional function to free the context.<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Works for me, although I'm not sure NULL callbackData is ever<br>
valid/usefull.<br>
</blockquote>
As an example, if you have a LocalFree or whatever on Windows, you just<br>
need the array parameter, so NULL callbackData is needed. Where array<br>
and callbackData might be needed is something like where you need the<br>
array, but callbackData is the arena to free it from. Currently, you<br>
only get one or the other.<br>
<br>
--Ben<br>
</blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>
<br>
______________________________<u></u>_________________<br>
Powered by <a href="http://www.kitware.com" target="_blank">www.kitware.com</a><br>
<br>
Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html" target="_blank">http://www.kitware.com/<u></u>opensource/opensource.html</a><br>
<br>
Follow this link to subscribe/unsubscribe:<br>
<a href="http://www.vtk.org/mailman/listinfo/vtk-developers" target="_blank">http://www.vtk.org/mailman/<u></u>listinfo/vtk-developers</a><br>
<br>
</div></div></blockquote></div><br></div>