[Cython] memoryview slice transpose

Stefan Behnel stefan_ml at behnel.de
Sun Apr 6 12:12:19 CEST 2014


Syam Gadde, 27.03.2014 21:29:
> I wanted to re-offer for discussion a fix for a bug I reported a while 
> back.  The code that breaks is this:
> 
> import numpy
> cimport numpy
> 
> def testfunc():
>     a = numpy.arange(12).reshape([3,4])
>     cdef numpy.int_t[:,:] a_view = a
>     cdef numpy.int_t[:,:] b = a_view[:,:].T
> 
> One problem is that when a memoryview slice is decremented, the .memview 
> and .data fields are not set to NULL, and any error that causes a jump 
> to cleanup code will attempt to decref it again.
> 
> The second problem (I think) is that assignment of a transpose of 
> memoryview slices to a variable is not resulting in an incref on the 
> underlying slice, even though the variable is not a temporary and 
> continues to persist.
> 
> Here is a patch that solves the problem for me.
> 
> https://github.com/SyamGadde/cython/commit/5739d8b908f18c4fc9103ef04e39964d61af3495

Hmm, I can't see why the additional NULL setting would change anything.
That's what the call to put_xdecref_memoryviewslice() already did that
immediately precedes them (it actually calls "__Pyx_XDEC_MEMVIEW()" in
MemoryView_C.c).


> The part I am least sure about is removing the "if" qualifications on 
> the incref and decref:
> 
>    if self.obj.is_name  or self.obj.is_attribute and self.obj.is_memslice_transpose:
> 
> that was obviously there for a reason, but it causes problems in the above case.  If there is a less extreme solution I'd be happy to take it.

It's more likely that this was the change that made the difference. I can't
say why the original code behaved that way, but it may well be that it
misbehaves in an error case. Essentially, it doesn't incref the slice in
certain cases (as an optimisation?), and if an error occurs, it might still
end up trying to decref it. I think it's worth investigating that a bit
further.

Stefan



More information about the cython-devel mailing list