def args_to_kernel_data_struct(kinds, argtypes): # Build up the kernel data structure. Currently, this means # adding a shape field for each array argument. First comes # the kernel data prefix with a spot for the 'owner' reference added. input_field_indices = [] kernel_data_fields = [Type.struct([int8_p_type]*3)] kernel_data_ctypes_fields = [('base', JITCKernelData)] for i, (kind, a) in enumerate(izip(kinds, argtypes)): if isinstance(kind, tuple): if kind[0] != lla.C_CONTIGUOUS: raise ValueError('only support C contiguous array presently') input_field_indices.append(len(kernel_data_fields)) kernel_data_fields.append(Type.array( intp_type, len(bek.dshapes[i])-1)) kernel_data_ctypes_fields.append(('operand_%d' % i, c_ssize_t * (len(bek.dshapes[i])-1))) elif kind in [lla.SCALAR, lla.POINTER]: input_field_indices.append(None) else: raise TypeError(("unbound_single_ckernel codegen doesn't " + "support the parameter kind %r yet") % (k,)) # Make an LLVM and ctypes type for the extra data pointer. kernel_data_llvmtype = Type.struct(kernel_data_fields) class kernel_data_ctypestype(ctypes.Structure): _fields_ = kernel_data_ctypes_fields return (kernel_data_llvmtype, kernel_data_ctypestype)
def build_llvm_src_ptrs(builder, src_ptr_arr_arg, dshapes, kinds, argtypes): args = [] for i, (dshape, kind, argtype) in enumerate(izip(dshapes, kinds, argtypes)): raw_ptr_arg = builder.load(builder.gep(src_ptr_arr_arg, (lc.Constant.int(intp_type, i),))) arg = build_llvm_arg_ptr(builder, raw_ptr_arg, dshape, kind, argtype) args.append(arg) return args
def test_element_iter_write_buffered(self): a = nd.array([1, 2, 3, 4, 5], access='rw').ucast(ndt.int64) dd = DyNDDataDescriptor(a) self.assertEqual(dd.dshape, datashape.dshape('5, int64')) with dd.element_write_iter() as ge: self.assertTrue(isinstance(ge, IElementWriteIter)) for val, ptr in izip([5,7,4,5,3], ge): x = ctypes.c_int64(val) ctypes.memmove(ptr, ctypes.addressof(x), 8) self.assertEqual(dd_as_py(dd), [5,7,4,5,3])
def test_element_iter_write(self): a = np.array([1, 2, 3, 4, 5], dtype=np.int32) dd = NumPyDataDescriptor(a) self.assertEqual(dd.dshape, datashape.dshape('5, int32')) with dd.element_write_iter() as ge: self.assertTrue(isinstance(ge, IElementWriteIter)) for val, ptr in izip([5,7,4,5,3], ge): x = ctypes.c_int32(val) ctypes.memmove(ptr, ctypes.addressof(x), 4) self.assertEqual(dd_as_py(dd), [5,7,4,5,3])
def test_binary_kerneltree(self): # Create some simple blaze funcs, using Numba def _add(a,b): return a + b def _mul(a,b): return a * b add = BlazeFunc('add',[('f8(f8,f8)', _add), ('c16(c16,c16)', _add)]) mul = BlazeFunc('mul', {(double,)*3: _mul, (c128,)*3: _mul}) # Array data and expression af = blaze.array([[1,2,3], [4,5,6]],dshape=double) bf = blaze.array([2,3,4],dshape=double) cf = add(af,bf) df = mul(cf,cf) ubck = df._data.kerneltree.unbound_single_ckernel # Allocate the result, and run the kernel across the arguments result = blaze.zeros(df.dshape) args = [arg.arr._data for arg in df._data.args] ck = ubck.bind(result._data, args) execute_expr_single(result._data, args, df._data.kerneltree.kernel.dshapes[-1], df._data.kerneltree.kernel.dshapes[:-1], ck) self.assertEqual(dd_as_py(result._data), [[(a+b) * (a+b) for a, b in izip(a1, b1)] for a1, b1 in izip( [[1,2,3], [4,5,6]], [[2,3,4]]*2)]) # Use blaze.eval to evaluate cf and df into concrete arrays cf2 = blaze.eval(cf) self.assertEqual(dd_as_py(cf2._data), [[(a+b) for a, b in izip(a1, b1)] for a1, b1 in izip( [[1,2,3], [4,5,6]], [[2,3,4]]*2)]) df2 = blaze.eval(df) self.assertEqual(dd_as_py(df2._data), [[(a+b) * (a+b) for a, b in izip(a1, b1)] for a1, b1 in izip( [[1,2,3], [4,5,6]], [[2,3,4]]*2)])
def test_broadcast_to_two_d(self): # Set up our data buffers src0 = data_descriptor_from_ctypes(ctypes.c_double(12), writable=False) src0_broadcast = [[12] * 3] * 2 src1_data = (ctypes.c_double * 3)() src1_list = [3, 9, 1] src1_broadcast = [src1_list] * 2 for i, val in enumerate(src1_list): src1_data[i] = val src1 = data_descriptor_from_ctypes(src1_data, writable=False) src2_data = (ctypes.c_double * 3 * 2)() src2_list = [[5, 3, -2], [-1, 4, 9]] src2_broadcast = src2_list for j, val_j in enumerate(src2_list): for i, val in enumerate(val_j): src2_data[j][i] = val src2 = data_descriptor_from_ctypes(src2_data, writable=False) dst = data_descriptor_from_ctypes((ctypes.c_double * 3 * 2)(), writable=True) # Do assignments with the different permuations of the source arguments execute_expr_single(dst, [src0, src1, src2], datashape.float64, [datashape.float64]*3, self.muladd) self.assertEqual(dd_as_py(dst), [[(x + 1) * y + z for x, y, z in izip(*tmp)] for tmp in izip(src0_broadcast, src1_broadcast, src2_broadcast)]) execute_expr_single(dst, [src0, src2, src1], datashape.float64, [datashape.float64]*3, self.muladd) self.assertEqual(dd_as_py(dst), [[(x + 1) * y + z for x, z, y in izip(*tmp)] for tmp in izip(src0_broadcast, src1_broadcast, src2_broadcast)]) execute_expr_single(dst, [src1, src0, src2], datashape.float64, [datashape.float64]*3, self.muladd) self.assertEqual(dd_as_py(dst), [[(x + 1) * y + z for y, x, z in izip(*tmp)] for tmp in izip(src0_broadcast, src1_broadcast, src2_broadcast)]) execute_expr_single(dst, [src1, src2, src0], datashape.float64, [datashape.float64]*3, self.muladd) self.assertEqual(dd_as_py(dst), [[(x + 1) * y + z for z, x, y in izip(*tmp)] for tmp in izip(src0_broadcast, src1_broadcast, src2_broadcast)]) execute_expr_single(dst, [src2, src0, src1], datashape.float64, [datashape.float64]*3, self.muladd) self.assertEqual(dd_as_py(dst), [[(x + 1) * y + z for y, z, x in izip(*tmp)] for tmp in izip(src0_broadcast, src1_broadcast, src2_broadcast)]) execute_expr_single(dst, [src2, src1, src0], datashape.float64, [datashape.float64]*3, self.muladd) self.assertEqual(dd_as_py(dst), [[(x + 1) * y + z for z, y, x in izip(*tmp)] for tmp in izip(src0_broadcast, src1_broadcast, src2_broadcast)])