def test_ckernel_deferred_from_pyfunc(self): # Test wrapping make_assignment_ckernel as a deferred ckernel def instantiate_assignment(out_ckb, ckb_offset, types, meta, kerntype, ectx): out_ckb = _lowlevel.CKernelBuilderStruct.from_address(out_ckb) return _lowlevel.make_assignment_ckernel(out_ckb, ckb_offset, types[0], meta[0], types[1], meta[1], 'expr', kerntype, ectx) ckd = _lowlevel.ckernel_deferred_from_pyfunc(instantiate_assignment, [ndt.string, ndt.date]) self.assertEqual(nd.as_py(ckd.types), [ndt.string, ndt.date]) out = nd.empty(ndt.string) in0 = nd.array('2012-11-05', ndt.date) ckd.__call__(out, in0) self.assertEqual(nd.as_py(out), '2012-11-05') # Also test it as a lifted kernel ckd_lifted = _lowlevel.lift_ckernel_deferred(ckd, ['3 * var * string', '3 * var * date']) self.assertEqual(nd.as_py(ckd_lifted.types), [ndt.type('3 * var * string'), ndt.type('3 * var * date')]) out = nd.empty('3 * var * string') from datetime import date in0 = nd.array([['2013-03-11', date(2010, 10, 10)], [date(1999, 12, 31)], []], type='3 * var * date') ckd_lifted.__call__(out, in0) self.assertEqual(nd.as_py(out), [['2013-03-11', '2010-10-10'], ['1999-12-31'], []])
def test_lift_ckernel(self): # First get a ckernel from numpy requiregil = False ckd = _lowlevel.ckernel_deferred_from_ufunc(np.ldexp, (np.float64, np.float64, np.int32), requiregil) self.assertEqual(nd.as_py(ckd.types), [ndt.float64, ndt.float64, ndt.int32]) # Now lift it ckd_lifted = _lowlevel.lift_ckernel_deferred(ckd, ['var * var * float64', 'strided * var * float64', 'strided * 1 * int32']) self.assertEqual(nd.as_py(ckd_lifted.types), [ndt.type(x) for x in ['var * var * float64', 'strided * var * float64', 'strided * 1 * int32']]) # Create some compatible arguments out = nd.empty('var * var * float64') in0 = nd.array([[1, 2, 3], [4, 5], [6], [7,9,10]], type='strided * var * float64') in1 = nd.array([[-1], [10], [100], [-12]], type='strided * 1 * int32') # Instantiate and call the kernel on these arguments ckd_lifted.__call__(out, in0, in1) # Verify that we got the expected result self.assertEqual(nd.as_py(out), [[0.5, 1.0, 1.5], [4096.0, 5120.0], [float(6*2**100)], [0.001708984375, 0.002197265625, 0.00244140625]])
def op_ckernel(self, op): op_ndim = len(op.type.shape) result_ndim = self.env.get('result-ndim', 0) ckernel, args = op.args in_types = [self.get_arg_type(arg) for arg in args[1:]] out_type = ndt.type(str(args[0].type)) if isinstance(ckernel, dict): tag = ckernel['tag'] if tag == 'elwise': ck = ckernel['ckernel'] if op.metadata['rank'] < op_ndim and \ self.env.get('stream-outer', False) and result_ndim == op_ndim: # Replace the leading dimension type with 'strided' in each operand # if we're streaming it for processing BLZ # TODO: Add dynd tp.subarray(N) function like datashape has for i, tp in enumerate(in_types): if tp.ndim == result_ndim: in_types[i] = ndt.make_strided_dim(tp.element_type) out_type = ndt.make_strided_dim(out_type.element_type) op.args[0] = _lowlevel.lift_ckernel_deferred(ck, [out_type] + in_types) elif tag == 'reduction': ck = ckernel['ckernel'] assoc = ckernel['assoc'] comm = ckernel['comm'] ident = ckernel['ident'] ident = None if ident is None else nd.asarray(ident) axis = ckernel['axis'] keepdims = ckernel['keepdims'] op.args[0] = _lowlevel.lift_reduction_ckernel_deferred( ck, in_types[0], axis=axis, keepdims=keepdims, associative=assoc, commutative=comm, reduction_identity=ident) elif tag == 'rolling': ck = ckernel['ckernel'] window = ckernel['window'] minp = ckernel['minp'] if minp != 0: raise ValueError('rolling window with minp != 0 not supported yet') op.args[0] = _lowlevel.make_rolling_ckernel_deferred(out_type, in_types[0], ck, window) elif tag == 'ckfactory': ckfactory = ckernel['ckernel_factory'] ck = ckfactory(out_type, *in_types) op.args[0] = ck else: raise RuntimeError('unnrecognized ckernel tag %s' % tag) else: op.args[0] = ckernel
def op_ckernel(self, op): op_ndim = len(op.type.shape) if op.metadata['rank'] < op_ndim: result_ndim = self.env.get('result-ndim', 0) ckernel, args = op.args in_types = [self.get_arg_type(arg) for arg in args[1:]] out_type = ndt.type(str(args[0].type)) # Replace the leading dimension type with 'strided' in each operand # if we're streaming it for processing BLZ if self.env.get('stream-outer', False) and result_ndim == op_ndim: # TODO: Add dynd tp.subarray(N) function like datashape has for i, tp in enumerate(in_types): if tp.ndim == result_ndim: in_types[i] = ndt.make_strided_dim(tp.element_type) out_type = ndt.make_strided_dim(out_type.element_type) op.args[0] = _lowlevel.lift_ckernel_deferred(ckernel, [out_type] + in_types)
def op_ckernel(self, op): op_ndim = len(op.type.shape) if op.metadata['rank'] < op_ndim: result_ndim = self.env.get('result-ndim', 0) ckernel, args = op.args in_types = [self.get_arg_type(arg) for arg in args[1:]] out_type = ndt.type(str(args[0].type)) # Replace the leading dimension type with 'strided' in each operand # if we're streaming it for processing BLZ if self.env.get('stream-outer', False) and result_ndim == op_ndim: # TODO: Add dynd tp.subarray(N) function like datashape has for i, tp in enumerate(in_types): if tp.ndim == result_ndim: in_types[i] = ndt.make_strided_dim(tp.element_type) out_type = ndt.make_strided_dim(out_type.element_type) op.args[0] = _lowlevel.lift_ckernel_deferred( ckernel, [out_type] + in_types)
def test_ctypes_callback_deferred(self): # Create a deferred ckernel via a closure def instantiate_ckernel(out_ckb, ckb_offset, types, meta, kerntype, ectx): 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) ckd = _lowlevel.ckernel_deferred_from_pyfunc(instantiate_ckernel, [ndt.int32, ndt.float64]) # Test calling the ckd out = nd.empty(ndt.int32) in0 = nd.array(4.0, type=ndt.float64) ckd.__call__(out, in0) self.assertEqual(nd.as_py(out), 14) # Also call it lifted ckd_lifted = _lowlevel.lift_ckernel_deferred( ckd, ['2 * var * int32', '2 * var * float64']) out = nd.empty('2 * var * int32') in0 = nd.array([[1.0, 3.0, 2.5], [1.25, -1.5]], type='2 * var * float64') ckd_lifted.__call__(out, in0) self.assertEqual(nd.as_py(out), [[3, 10, 8], [4, -5]])
def test_ctypes_callback_deferred(self): # Create a deferred ckernel via a closure def instantiate_ckernel(out_ckb, ckb_offset, types, meta, kerntype, ectx): 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) ckd = _lowlevel.ckernel_deferred_from_pyfunc(instantiate_ckernel, [ndt.int32, ndt.float64]) # Test calling the ckd out = nd.empty(ndt.int32) in0 = nd.array(4.0, type=ndt.float64) ckd.__call__(out, in0) self.assertEqual(nd.as_py(out), 14) # Also call it lifted ckd_lifted = _lowlevel.lift_ckernel_deferred(ckd, ['2 * var * int32', '2 * var * float64']) out = nd.empty('2 * var * int32') in0 = nd.array([[1.0, 3.0, 2.5], [1.25, -1.5]], type='2 * var * float64') ckd_lifted.__call__(out, in0) self.assertEqual(nd.as_py(out), [[3, 10, 8], [4, -5]])