def test_array_from_ptr(self): # cfixed_dim arrmeta is redundant so this is ok a = (ctypes.c_int32 * 3)() a[0] = 3 a[1] = 6 a[2] = 9 # Readwrite version using cfixed b = _lowlevel.array_from_ptr('cfixed[3] * int32', ctypes.addressof(a), a, 'readwrite') self.assertEqual(_lowlevel.data_address_of(b), ctypes.addressof(a)) self.assertEqual(nd.dshape_of(b), '3 * int32') self.assertEqual(nd.as_py(b), [3, 6, 9]) b[1] = 10 self.assertEqual(a[1], 10) # Readonly version using cfixed b = _lowlevel.array_from_ptr('cfixed[3] * int32', ctypes.addressof(a), a, 'readonly') self.assertEqual(nd.as_py(b), [3, 10, 9]) def assign_to(b): b[1] = 100 self.assertRaises(RuntimeError, assign_to, b) # Using a fixed dim default-constructs the arrmeta, so works too b = _lowlevel.array_from_ptr('3 * int32', ctypes.addressof(a), a, 'readonly') self.assertEqual(nd.as_py(b), [3, 10, 9]) # Should get an error if we try strided, because the size is unknown self.assertRaises(RuntimeError, lambda: _lowlevel.array_from_ptr('strided * int32', ctypes.addressof(a), a, 'readonly'))
def data_descriptor_from_cffi(ffi, cdata, writable): """ Parameters ---------- ffi : cffi.FFI The cffi namespace which contains the cdata. cdata : cffi.CData The cffi data object which owns the data. writable : bool Should be true if the data is writable, flase if it's read-only. """ if not isinstance(cdata, ffi.CData): raise TypeError('object is not a cffi.CData object, has type %s' % type(cdata)) owner = (ffi, cdata) # Get the raw pointer out of the cdata as an integer ptr = int(ffi.cast('uintptr_t', ffi.cast('char *', cdata))) ds = datashape.from_cffi(ffi, ffi.typeof(cdata)) if (isinstance(ds, datashape.DataShape) and isinstance(ds[0], datashape.TypeVar)): # If the outermost dimension is an array without fixed # size, get its size from the data ds = datashape.DataShape((datashape.Fixed(len(cdata)),) + ds[1:]) access = "readwrite" if writable else "readonly" dyndarr = _lowlevel.array_from_ptr(ndt.type(str(ds)), ptr, owner, access) return DyNDDataDescriptor(dyndarr)
def data_descriptor_from_cffi(ffi, cdata, writable): """ Parameters ---------- ffi : cffi.FFI The cffi namespace which contains the cdata. cdata : cffi.CData The cffi data object which owns the data. writable : bool Should be true if the data is writable, flase if it's read-only. """ if not isinstance(cdata, ffi.CData): raise TypeError('object is not a cffi.CData object, has type %s' % type(cdata)) owner = (ffi, cdata) # Get the raw pointer out of the cdata as an integer ptr = int(ffi.cast('uintptr_t', ffi.cast('char *', cdata))) ds = datashape.from_cffi(ffi, ffi.typeof(cdata)) if (isinstance(ds, datashape.DataShape) and isinstance(ds[0], datashape.TypeVar)): # If the outermost dimension is an array without fixed # size, get its size from the data ds = datashape.DataShape(*(datashape.Fixed(len(cdata)), ) + ds[1:]) access = "readwrite" if writable else "readonly" dyndarr = _lowlevel.array_from_ptr(ndt.type(str(ds)), ptr, owner, access) return DyNDDataDescriptor(dyndarr)
def test_array_from_ptr(self): a = (ctypes.c_int32 * 3)() a[0] = 3 a[1] = 6 a[2] = 9 # Readwrite version b = _lowlevel.array_from_ptr(ndt.type('3 * int32'), ctypes.addressof(a), a, 'readwrite') self.assertEqual(_lowlevel.data_address_of(b), ctypes.addressof(a)) self.assertEqual(nd.dshape_of(b), '3 * int32') self.assertEqual(nd.as_py(b), [3, 6, 9]) b[1] = 10 self.assertEqual(a[1], 10) # Readonly version b = _lowlevel.array_from_ptr(ndt.type('3 * int32'), ctypes.addressof(a), a, 'readonly') self.assertEqual(nd.as_py(b), [3, 10, 9]) def assign_to(b): b[1] = 100 self.assertRaises(RuntimeError, assign_to, b)
def test_array_from_ptr_struct(self): class SomeStruct(ctypes.Structure): _fields_ = [('x', ctypes.c_int8), ('y', ctypes.c_int32), ('z', ctypes.c_double)] a = SomeStruct() a.x = 1 a.y = 2 a.z = 3.75 b = _lowlevel.array_from_ptr('{x: int8, y: int32, z: float64}', ctypes.addressof(a), a, 'readonly') self.assertEqual(nd.as_py(b, tuple=True), (1, 2, 3.75))
def write_single(self, idx, ptr): if len(idx) != self.nindex: raise IndexError('Incorrect number of indices (got %d, require %d)' % (len(idx), self.nindex)) idx = tuple(operator.index(i) for i in idx) # Create a temporary DyND array around the ptr data. # Note that we can't provide an owner because the parameter # is just the bare pointer. tmp = _lowlevel.array_from_ptr(self._c_dtype, ptr, None, 'readonly') # Use DyND's assignment to set the values self._dyndarr[idx] = tmp
def data_descriptor_from_ctypes(cdata, writable): """ Parameters ---------- cdata : ctypes data instance The ctypes data object which owns the data. writable : bool Should be true if the data is writable, flase if it's read-only. """ ds = datashape.from_ctypes(type(cdata)) access = "readwrite" if writable else "readonly" dyndarr = _lowlevel.array_from_ptr(ndt.type(str(ds)), ctypes.addressof(cdata), cdata, access) return DyNDDataDescriptor(dyndarr)
def data_descriptor_from_ctypes(cdata, writable): """ Parameters ---------- cdata : ctypes data instance The ctypes data object which owns the data. writable : bool Should be true if the data is writable, flase if it's read-only. """ ds = datashape.from_ctypes(type(cdata)) access = "readwrite" if writable else "readonly" dyndtp = " * ".join(["cfixed[%d]" % int(x) for x in ds[:-1]] + [str(ds[-1])]) dyndarr = _lowlevel.array_from_ptr(ndt.type(dyndtp), ctypes.addressof(cdata), cdata, access) return DyND_DDesc(dyndarr)
def data_descriptor_from_ctypes(cdata, writable): """ Parameters ---------- cdata : ctypes data instance The ctypes data object which owns the data. writable : bool Should be true if the data is writable, flase if it's read-only. """ ds = datashape.from_ctypes(type(cdata)) access = "readwrite" if writable else "readonly" dyndtp = ' * '.join(['cfixed[%d]' % int(x) for x in ds[:-1]] + [str(ds[-1])]) dyndarr = _lowlevel.array_from_ptr(ndt.type(dyndtp), ctypes.addressof(cdata), cdata, access) return DyND_DDesc(dyndarr)
def test_array_from_ptr_blockref(self): a = ctypes.pointer(ctypes.c_double(1.25)) b = _lowlevel.array_from_ptr('pointer[float64]', ctypes.addressof(a), a, 'readonly') self.assertEqual(nd.as_py(b), 1.25)