def as_BFarray(self): # ***TODO: The caching here is broken because of shape, strides and ctypes.data # How to fix? #*if self._BFarray is not None: #* return self._BFarray a = _bf.BFarray() a.data = self.ctypes.data a.space = Space(self.bf.space).as_BFspace() a.dtype = self.bf.dtype.as_BFdtype() a.immutable = not self.flags['WRITEABLE'] a.ndim = len(self.shape) # HACK WAR for backend not yet supporting ndim=0 (scalar arrays) if a.ndim == 0: a.ndim = 1 a.shape[0] = 1 a.strides[0] = self.bf.dtype.itemsize for d in range(len(self.shape)): a.shape[d] = self.shape[d] # HACK TESTING support for 'packed' arrays itemsize_bits = self.bf.dtype.itemsize_bits if itemsize_bits < 8: a.shape[a.ndim - 1] *= 8 // itemsize_bits for d in range(len(self.strides)): a.strides[d] = self.strides[d] a.big_endian = not self.bf.native a.conjugated = self.bf.conjugated return a
def readinto(self, buf): dst_space = Space(_get_space(buf)).as_BFspace() byte0 = 0 nbyte = buf.nbytes nbyte_copy = min(nbyte - byte0, self.nbyte - self.byte0) while nbyte_copy: _check( _bf.bfMemcpy(buf.ctypes.data + byte0, dst_space, self.block.ptr + self.byte0, _bf.BF_SPACE_SYSTEM, nbyte_copy)) byte0 += nbyte_copy self.byte0 += nbyte_copy nbyte_copy = min(nbyte - byte0, self.nbyte - self.byte0) if self.nbyte - self.byte0 == 0: self.block.close() try: self._open_next_block() except StopIteration: break return byte0
def __new__(cls, base=None, space=None, shape=None, dtype=None, buffer=None, offset=0, strides=None, native=None, conjugated=None): if isinstance(shape, int): shape = [shape] ownbuffer = None if base is not None: if (shape is not None or # dtype is not None or buffer is not None or offset != 0 or strides is not None or native is not None): raise ValueError('Invalid combination of arguments when base ' 'is specified') if 'cupy' in sys.modules: from cupy import ndarray as cupy_ndarray if isinstance(base, cupy_ndarray): return ndarray.__new__(cls, space='cuda', buffer=int(base.data), shape=base.shape, dtype=base.dtype, strides=base.strides, native=np.dtype(base.dtype).isnative) if 'pycuda' in sys.modules: from pycuda.gpuarray import GPUArray as pycuda_GPUArray if isinstance(base, pycuda_GPUArray): return ndarray.__new__(cls, space='cuda', buffer=int(base.gpudata), shape=base.shape, dtype=base.dtype, strides=base.strides, native=np.dtype(base.dtype).isnative) if dtype is not None: dtype = DataType(dtype) if space is None and dtype is None: if not isinstance(base, np.ndarray): base = np.asarray(base) # TODO: This may not be a good idea # Create view of base array obj = base.view(cls) # Note: This calls obj.__array_finalize__ # Allow conjugated to be redefined if conjugated is not None: obj.bf.conjugated = conjugated obj._update_BFarray() else: if not isinstance(base, np.ndarray): # Convert base to np.ndarray if dtype is not None: base = np.array(base, dtype=DataType(dtype).as_numpy_dtype()) else: base = np.array(base) if not isinstance(base, ndarray) and dtype is not None: base = base.astype(dtype.as_numpy_dtype()) base = ndarray(base) # View base as bf.ndarray if dtype is not None and base.bf.dtype != dtype: raise TypeError('Unable to convert type %s to %s during ' 'array construction' % (base.bf.dtype, dtype)) #base = base.view(cls #if dtype is not None: # base = base.astype(DataType(dtype).as_numpy_dtype()) if conjugated is None: conjugated = base.bf.conjugated # Create copy of base array obj = ndarray.__new__(cls, space=space, shape=base.shape, dtype=base.bf.dtype, strides=base.strides, native=base.bf.native, conjugated=conjugated) copy_array(obj, base) else: # Create new array if dtype is None: dtype = 'f32' # Default dtype dtype = DataType(dtype) if native is None: native = True # Default byteorder if conjugated is None: conjugated = False # Default unconjugated if strides is None: #itemsize = dtype.itemsize itemsize_bits = dtype.itemsize_bits # HACK to support 'packed' arrays, by folding the last # dimension of the shape into the dtype. # TODO: Consider using bit strides when dtype < 8 bits # It's hacky, but it may be worth it if itemsize_bits < 8: pack_factor = 8 // itemsize_bits if shape[-1] % pack_factor != 0 or not len(shape): raise ValueError("Array cannot be packed") shape = list(shape) shape[-1] //= pack_factor itemsize = 1 else: itemsize = itemsize_bits // 8 if len(shape): # This magic came from http://stackoverflow.com/a/32874295 strides = (itemsize * np.r_[1, np.cumprod(shape[::-1][:-1], dtype=np.int64)][::-1]) strides = tuple(strides) else: strides = tuple() nbyte = strides[0] * shape[0] if len(shape) else itemsize if buffer is None: # Allocate new buffer if space is None: space = 'system' # Default space if shape is None: raise ValueError('Either buffer or shape must be ' 'specified') ownbuffer = raw_malloc(nbyte, space) buffer = ownbuffer else: if space is None: #space = _get(_bf.bfGetSpace(buffer)) # TODO: raw_get_space should probably return string, and needs a better name space = str(Space(raw_get_space(buffer))) # TODO: Should move np.dtype() into as_numpy_dtype? dtype_np = np.dtype(dtype.as_numpy_dtype()) if not native: dtype_np = dtype_np.newbyteorder() data_buffer = _address_as_buffer(buffer, nbyte) obj = np.ndarray.__new__(cls, shape, dtype_np, data_buffer, offset, strides) obj.bf = BFArrayInfo(space, dtype, native, conjugated, ownbuffer) obj._update_BFarray() return obj