Different behavior of PyArray_SimpleNewFromData in Cython vs C++

162 views
Skip to first unread message

Dami Choi

unread,
Sep 17, 2020, 1:43:16 AM9/17/20
to cython-users
I'm trying to access a double* pointer in C++ from python by casting it to a numpy array using PyArray_SimpleNewFromData. However, doing so in C++ results in a memory leak, while doing so in Cython doesn't. 

Here is how I do it in C++:
PyObject* IClpSimplex::getReducedCosts(){
    npy_intp dims = getNumCols() + getNumRows();
    PyObject *Arr = PyArray_SimpleNewFromData( 1, &dims, NPY_DOUBLE, this->djRegion() );
    return Arr;
}

In Cython, I call the C++ function to get the PyObject* and cast it to an np array:
cpdef getReducedCosts(self):
    return <np.ndarray>self.CppSelf.getReducedCosts()

Here is how I do it in Cython:
cpdef getReducedCosts(self):
    cdef np.npy_intp dims = <np.npy_intp> (self.nCols + self.nRows)
    cdef double* ptr = <double*> self.CppSelf.djRegion()
    return np.PyArray_SimpleNewFromData(1, &dims, np.NPY_DOUBLE, ptr)
    return arr

When I looked at the C++ files generated from the Cython code, I found that if I use PyArray_SimpleNewFromData in C++, it Py_INCREF's but doesn't DECREF one of the variables, while for Cython it does:

Cython:
__Pyx_XDECREF(__pyx_r);
__pyx_t_3 = PyArray_SimpleNewFromData(1, (&__pyx_v_dims), NPY_DOUBLE, __pyx_v_ptr); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 480, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__pyx_r = __pyx_t_3;
__pyx_t_3 = 0;
...
__Pyx_XDECREF(__pyx_t_3);

C++:
__Pyx_XDECREF(__pyx_r);
__pyx_t_5 = __pyx_v_self->CppSelf->getReducedCosts();
__Pyx_INCREF(((PyObject *)((PyArrayObject *)__pyx_t_5)));
__pyx_r = ((PyObject *)__pyx_t_5);


 and there is no __Pyx_XDECREF(__pyx_t_5);


Is this a bug? Or am I missing something in my C++ code? Why would there be a Py_INCREF but not a DECREF?


da-woods

unread,
Sep 17, 2020, 1:15:20 PM9/17/20
to cython...@googlegroups.com
You don't say how you wrap the C++ getReducingCosts. However, you probably want to wrap it as `object getReducingCosts()`. If you do that then Cython should handle the reference counting appropriately and you won't need the cast.
--

---
You received this message because you are subscribed to the Google Groups "cython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cython-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cython-users/1810614b-d889-478f-abf7-95939afa77ebn%40googlegroups.com.


Reply all
Reply to author
Forward
0 new messages