def setUp(self): # Create a unary single ckernel for the tests to use def my_kernel_func(dst_ptr, src_ptr, kdp): dst = ctypes.c_double.from_address(dst_ptr) src = ctypes.c_float.from_address(src_ptr) dst.value = src.value * src.value my_callback = ckernel.UnarySingleOperation(my_kernel_func) # The ctypes callback object is both the function and the owner self.sqr = ckernel.wrap_ckernel_func(my_callback, my_callback)
def test_ctypes_callback(self): # Create a ckernel directly with ctypes def my_kernel_func(dst_ptr, src_ptr, kdp): dst = ctypes.c_int32.from_address(dst_ptr) src = ctypes.c_double.from_address(src_ptr) dst.value = int(src.value * 3.5) my_callback = _lowlevel.UnarySingleOperation(my_kernel_func) with _lowlevel.ckernel.CKernelBuilder() as ckb: # The ctypes callback object is both the function and the owner ckernel.wrap_ckernel_func(ckb, 0, my_callback, my_callback) # Delete the callback to make sure the ckernel is holding a reference del my_callback # Make some memory and call the kernel src_val = ctypes.c_double(4.0) dst_val = ctypes.c_int32(-1) ck = ckb.ckernel(_lowlevel.UnarySingleOperation) ck(ctypes.addressof(dst_val), ctypes.addressof(src_val)) self.assertEqual(dst_val.value, 14)
def setUp(self): # Create a ternary single ckernel @ckernel.ExprSingleOperation def my_ternary_func(dst_ptr, src_ptr, kdp): dst = ctypes.c_double.from_address(dst_ptr) class binary_src_arg(ctypes.Structure): _fields_ = [('src0', ctypes.POINTER(ctypes.c_double)), ('src1', ctypes.POINTER(ctypes.c_double)), ('src2', ctypes.POINTER(ctypes.c_double))] src_args = binary_src_arg.from_address(ctypes.addressof(src_ptr.contents)) src0 = src_args.src0.contents src1 = src_args.src1.contents src2 = src_args.src2.contents dst.value = (src0.value + 1) * src1.value + src2.value #print(src0, src1, src2, '->', dst, '--', hex(dst_ptr)) # The ctypes callback object is both the function and the owner self.muladd = ckernel.wrap_ckernel_func(my_ternary_func, my_ternary_func)
def instantiate_ckernel(out_ckb, ckb_offset, types, meta, kerntype): out_ckb = _lowlevel.CKernelBuilder(out_ckb) def my_kernel_func_single(dst_ptr, src_ptr, kdp): dst = ctypes.c_int32.from_address(dst_ptr) src = ctypes.c_double.from_address(src_ptr[0]) dst.value = int(src.value * 3.5) def my_kernel_func_strided(dst_ptr, dst_stride, src_ptr, src_stride, count, kdp): src_ptr0 = src_ptr[0] src_stride0 = src_stride[0] for i in range(count): my_kernel_func_single(dst_ptr, [src_ptr0], kdp) dst_ptr += dst_stride src_ptr0 += src_stride0 if kerntype == 'single': kfunc = _lowlevel.ExprSingleOperation(my_kernel_func_single) else: kfunc = _lowlevel.ExprStridedOperation(my_kernel_func_strided) return ckernel.wrap_ckernel_func(out_ckb, ckb_offset, kfunc, kfunc)