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 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)