[Numpy-discussion] Returning tuple of numpy arrays from a Numpy C-extension?

Åke Kullenberg ake.kullenberg at gmail.com
Tue Dec 27 04:52:59 EST 2011


After diving deeper in the docs I found the PyTuple_New alternative to
building tuples instead of Py_BuildValue. It seems to work fine.

But I am unsure of the INCREF/DECREF refcounting thing. Will I need any of
those in the code below?

Also, for generic c extensions, how can I check the refcounts of the
variables to see they're ok?

static PyObject *
test(PyObject *self, PyObject *args)
{
    PyArrayObject *py_in, *py_out, *py_out2;
    double *in, *out, *out2;
    int i, n, dims[2];
    if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &py_in))
        return NULL;
    if (NULL == py_in || not_doublevector(py_in)) return NULL;
    n = py_in->dimensions[0];
    dims[0] = n;
    dims[1] = 1;
    py_out = (PyArrayObject *) PyArray_FromDims(1, dims, NPY_DOUBLE);
    py_out2 = (PyArrayObject *) PyArray_FromDims(1, dims, NPY_DOUBLE);
    in = pyvector_to_Carrayptrs(py_in);
    out = pyvector_to_Carrayptrs(py_out);
    out2 = pyvector_to_Carrayptrs(py_out2);
    for (i=0; i<n; i++) {
        out[i] = in[i] * 2.0;
        out2[i] = in[i] * 3.0;
    }
    PyObject *tupleresult = PyTuple_New(2);
    PyTuple_SetItem(tupleresult, 0, PyArray_Return(py_out));
    PyTuple_SetItem(tupleresult, 1, PyArray_Return(py_out2));
    return tupleresult;
}

On Tue, Dec 27, 2011 at 5:11 PM, Åke Kullenberg <ake.kullenberg at gmail.com>wrote:

> I have put together a few c extensions following the documentation on
> http://www.scipy.org/Cookbook/C_Extensions/NumPy_arrays. There is however
> one thing that stumps me.
>
> To illustrate with a simple code snippet, the test function below
> multiplies the input numpy double array by two. So far so good. But how
> about if I want the function to return a tuple of two numpy arrays so I
> could do 'a, b = myCLib.test(c)' from a Python script? It's straight
> forward to convert C data structures to Python objects with Py_BuildValue,
> but how can I do this for numpy arrays instead?
>
> static PyObject *
> test(PyObject *self, PyObject *args)
> {
>     PyArrayObject *py_in, *py_out;
>     double *in, *out;
>     int i, n, dims[2];
>     if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &py_in))
>         return NULL;
>     if (NULL == py_in || not_doublevector(py_in)) return NULL;
>     n = py_in->dimensions[0];
>     dims[0] = n;
>     dims[1] = 1;
>     py_out = (PyArrayObject *) PyArray_FromDims(1, dims, NPY_DOUBLE);
>     in = pyvector_to_Carrayptrs(py_in);
>     out = pyvector_to_Carrayptrs(py_out);
>     for (i=0; i<n; i++) {
>         out[i] = in[i] * 2.0;
>     }
>     return PyArray_Return(py_out);
> }
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20111227/703be0fb/attachment.html>


More information about the NumPy-Discussion mailing list