def alloc(self, shape, dtype): """ Allocate memory. Parameters ---------- shape : tuple of ints Shape of the allocated array. dtype : numpy.dtype The data type of the raw data. Returns ------- pointer, memfree_args 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 "memfree" call. """ size = int(reduce(mul, shape)) ctype = dtype_to_ctype(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)) # cast to 1D array of the specified size ctype_1d = ctype * size buf = ctypes.cast(c_pointer, ctypes.POINTER(ctype_1d)).contents pointer = np.frombuffer(buf, dtype=dtype).reshape(shape) return (pointer, memfree_args)
def _arg_defaults(self, allocator, alias=None): # Lazy initialization if `allocator` is necessary as the `allocator` # type isn't really known until an Operator is constructed self._allocator = allocator target = alias or self.target for i, halo in enumerate(self.halos): entry = self.value[i] # Buffer size for this peer shape = [] for dim, side in zip(*halo): try: shape.append(getattr(target._size_owned[dim], side.name)) except AttributeError: assert side is CENTER shape.append(target._size_domain[dim]) entry.sizes = (c_int*len(shape))(*shape) # Allocate the send/recv buffers size = reduce(mul, shape) ctype = dtype_to_ctype(target.dtype) entry.bufg, bufg_memfree_args = allocator._alloc_C_libcall(size, ctype) entry.bufs, bufs_memfree_args = allocator._alloc_C_libcall(size, ctype) # The `memfree_args` will be used to deallocate the buffer upon returning # from C-land self._memfree_args.extend([bufg_memfree_args, bufs_memfree_args]) return {self.name: self.value}
def _arg_defaults(self, alias=None): function = alias or self.function for i, halo in enumerate(self.halos): entry = self.value[i] # Buffer size for this peer shape = [] for dim, side in zip(*halo): try: shape.append(getattr(function._size_owned[dim], side.name)) except AttributeError: assert side is CENTER shape.append(function._size_domain[dim]) entry.sizes = (c_int * len(shape))(*shape) # Allocate the send/recv buffers size = reduce(mul, shape) ctype = dtype_to_ctype(function.dtype) entry.bufg, bufg_memfree_args = self._allocator._alloc_C_libcall( size, ctype) entry.bufs, bufs_memfree_args = self._allocator._alloc_C_libcall( size, ctype) # The `memfree_args` will be used to deallocate the buffer upon returning # from C-land self._memfree_args.extend([bufg_memfree_args, bufs_memfree_args]) return {self.name: self.value}
def _data_buffer(self): ctype = dtype_to_ctype(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 _data_buffer(self): num_elements = self._data.grid.get_num_storage_elements() shape = self.shape_allocated ctype_1d = dtype_to_ctype(self.dtype) * reduce(mul, shape) if num_elements != reduce(mul, shape): warning("num_storage_elements(%d) != reduce(mul, %s)", num_elements, str(shape)) buf = ctypes.cast(int(self._data.grid.get_raw_storage_buffer()), ctypes.POINTER(ctype_1d)).contents return np.frombuffer(buf, dtype=self.dtype).reshape(shape)
def _data_buffer(self): num_elements = self._data.grid.get_num_storage_elements() shape = self.shape_allocated ctype_1d = dtype_to_ctype(self.dtype) * reduce(mul, shape) if num_elements != reduce(mul, shape): warning("num_storage_elements(%d) != reduce(mul, %s)", num_elements, str(shape)) buf = ctypes.cast( int(self._data.grid.get_raw_storage_buffer()), ctypes.POINTER(ctype_1d)).contents return np.frombuffer(buf, dtype=self.dtype).reshape(shape)
def alloc(self, shape, dtype): """ Allocate memory. Parameters ---------- shape : tuple of ints Shape of the allocated array. dtype : numpy.dtype The data type of the raw data. Returns ------- pointer, memfree_args 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 "memfree" call. """ size = int(reduce(mul, shape)) ctype = dtype_to_ctype(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)) # cast to 1D array of the specified size ctype_1d = ctype * size buf = ctypes.cast(c_pointer, ctypes.POINTER(ctype_1d)).contents pointer = np.frombuffer(buf, dtype=dtype) # pointer.reshape should not be used here because it may introduce a copy # From https://docs.scipy.org/doc/numpy/reference/generated/numpy.reshape.html: # It is not always possible to change the shape of an array without copying the # data. If you want an error to be raised when the data is copied, you should # assign the new shape to the shape attribute of the array: pointer.shape = shape return (pointer, memfree_args)
def _arg_defaults(self, alias=None): function = alias or self.function for i, halo in enumerate(self.halos): entry = self.value[i] # Buffer size for this peer shape = [] for dim, side in zip(*halo): try: shape.append(getattr(function._size_owned[dim], side.name)) except AttributeError: assert side is CENTER shape.append(function._size_domain[dim]) entry.sizes = (c_int*len(shape))(*shape) # Allocate the send/recv buffers size = reduce(mul, shape) ctype = dtype_to_ctype(function.dtype) entry.bufg, bufg_memfree_args = self._allocator._alloc_C_libcall(size, ctype) entry.bufs, bufs_memfree_args = self._allocator._alloc_C_libcall(size, ctype) # The `memfree_args` will be used to deallocate the buffer upon returning # from C-land self._memfree_args.extend([bufg_memfree_args, bufs_memfree_args]) return {self.name: self.value}
def _C_ctype(self): return dtype_to_ctype(self.dtype)
def _C_typename(self): return ctypes_to_cstr(POINTER(dtype_to_ctype(self.dtype)))
def _C_typename(self): return 'volatile %s' % ctypes_to_cstr(POINTER(dtype_to_ctype(self.dtype)))
def _C_ctype(self): return POINTER(dtype_to_ctype(self.dtype))
def _C_typename(self): words = [] if self.volatile: words.append('volatile') words.append(ctypes_to_cstr(POINTER(dtype_to_ctype(self.dtype)))) return ' '.join(words)
def _C_as_ndarray(self, dataobj): """Cast the data carried by a DiscreteFunction dataobj to an ndarray.""" shape = tuple(dataobj._obj.size[i] for i in range(self.ndim)) ctype_1d = dtype_to_ctype(self.dtype) * int(reduce(mul, shape)) buf = cast(dataobj._obj.data, POINTER(ctype_1d)).contents return np.frombuffer(buf, dtype=self.dtype).reshape(shape)