[Numpy-discussion] Owndata flag

Gregor Thalhammer gregor.thalhammer at gmail.com
Thu Dec 15 12:09:14 EST 2011


Am 15.12.2011 um 17:17 schrieb Fabrice Silva:

> How can one arbitrarily assumes that an ndarray owns its data ?
> 
> More explicitly, I have some temporary home-made C structure that holds
> a pointer to an array. I prepare (using Cython) an numpy.ndarray using
> the PyArray_NewFromDescr function. I can delete my temporary C structure
> without freeing the memory holding array, but I wish the numpy.ndarray
> becomes the owner of the data. 
> 
> How can do I do such thing ?

There is an excellent blog entry from Travis Oliphant, that describes how to create a ndarray from existing data without copy: http://blog.enthought.com/?p=62
The created array does not actually own the data, but its base attribute points to an object, which frees the memory if the numpy array gets deallocated. I guess this is the behavior you want to achieve. 
Here is a cython implementation (for a uint8 array)

Gregor



"""
see 'NumPy arrays with pre-allocated memory', http://blog.enthought.com/?p=62
"""

import numpy as np
from numpy cimport import_array, ndarray, npy_intp, set_array_base, PyArray_SimpleNewFromData, NPY_DOUBLE, NPY_INT, NPY_UINT8 

cdef extern from "stdlib.h":
   void* malloc(int size)
   void free(void *ptr)

cdef class MemoryReleaser:
   cdef void* memory

   def __cinit__(self):
       self.memory = NULL

   def __dealloc__(self):
       if self.memory:
           #release memory
           free(self.memory)
           print "memory released", hex(<long>self.memory)
           
cdef MemoryReleaser MemoryReleaserFactory(void* ptr):
   cdef MemoryReleaser mr = MemoryReleaser.__new__(MemoryReleaser)
   mr.memory = ptr
   return mr

cdef ndarray frompointer(void* ptr, int nbytes):
   import_array()
   #cdef int dims[1]
   #dims[0] = nbytes
   cdef npy_intp dims = <npy_intp>nbytes
   cdef ndarray arr = PyArray_SimpleNewFromData(1, &dims, NPY_UINT8, ptr)
   #TODO: check for error
   set_array_base(arr, MemoryReleaserFactory(ptr))
   
   return arr
   
def test_new_array_from_pointer():
    nbytes = 16
    cdef void* mem = malloc(nbytes)
    print "memory allocated", hex(<long>mem)
    return frompointer(mem, nbytes)




More information about the NumPy-Discussion mailing list