def alloc(self, shape, dtype): """ Allocate memory. :param shape: Shape of the array to allocate. :param dtype: Numpy datatype to allocate. :returns (pointer, free_handle): The first element of the tuple is the reference that can be used to access the data as a ctypes object. The second element is an opaque object that is needed only for the call to free. """ size = int(reduce(mul, shape)) ctype = numpy_to_ctypes(dtype) c_pointer, memfree_args = self._alloc_C_libcall(size, ctype) if c_pointer is None: raise RuntimeError("Unable to allocate %d elements in memory", str(size)) c_pointer = ctypes.cast( c_pointer, np.ctypeslib.ndpointer(dtype=dtype, shape=shape)) pointer = np.ctypeslib.as_array(c_pointer, shape=shape) return (pointer, memfree_args)
def malloc_aligned(shape, alignment=None, dtype=np.float32): """ Allocate memory using the C function malloc_aligned :param shape: Shape of the array to allocate :param alignment: number of bytes to align to. Defaults to page size if not set. :param dtype: Numpy datatype to allocate. Default to np.float32 :returns (pointer, data_pointer) the first element of the tuple is the reference that can be used to access the data as a ctypes object. The second element is the low-level reference that is needed only for the call to free. """ data_pointer = ctypes.cast(ctypes.c_void_p(), ctypes.POINTER(ctypes.c_float)) arraysize = int(reduce(mul, shape)) ctype = numpy_to_ctypes(dtype) if alignment is None: alignment = libc.getpagesize() ret = libc.posix_memalign(ctypes.byref(data_pointer), alignment, ctypes.c_ulong(arraysize * ctypes.sizeof(ctype))) if not ret == 0: error("Unable to allocate memory for shape %s", str(shape)) return None data_pointer = ctypes.cast( data_pointer, np.ctypeslib.ndpointer(dtype=dtype, shape=shape)) pointer = np.ctypeslib.as_array(data_pointer, shape=shape) return (pointer, data_pointer)
def _data_buffer(self): ctype = numpy_to_ctypes(self.dtype) cpointer = ctypes.cast(int(self._data.grid.get_raw_storage_buffer()), ctypes.POINTER(ctype)) ndpointer = np.ctypeslib.ndpointer(dtype=self.dtype, shape=self.shape_allocated) casted = ctypes.cast(cpointer, ndpointer) ndarray = np.ctypeslib.as_array(casted, shape=self.shape_allocated) return ndarray
def ndpointer(self): """Return a :class:`numpy.ndarray` view of the grid content.""" ctype = numpy_to_ctypes(self.dtype) cpointer = ctypes.cast(int(self.grid.get_raw_storage_buffer()), ctypes.POINTER(ctype)) ndpointer = np.ctypeslib.ndpointer(dtype=self.dtype, shape=self.shape) casted = ctypes.cast(cpointer, ndpointer) ndarray = np.ctypeslib.as_array(casted, shape=self.shape) return ndarray
def cfunction(self): """Returns the JIT-compiled C function as a ctypes.FuncPtr object.""" if self._lib is None: basename = self.compile self._lib = load(basename, self._compiler) self._lib.name = basename if self._cfunction is None: self._cfunction = getattr(self._lib, self.name) # Associate a C type to each argument for runtime type check argtypes = [] for i in self.parameters: if i.is_ScalarArgument: argtypes.append(numpy_to_ctypes(i.dtype)) elif i.is_TensorArgument: argtypes.append(np.ctypeslib.ndpointer(dtype=i.dtype, flags='C')) else: argtypes.append(ctypes.c_void_p) self._cfunction.argtypes = argtypes return self._cfunction