def test_overload_different_argcount(self): myfunc = ElementwiseBlazeFunc('test', 'ovld') # Two parameter overload ckd = _lowlevel.arrfunc_from_ufunc(np.add, (np.int32,) * 3, False) myfunc.add_overload("(int32, int32) -> int32", ckd) # One parameter overload ckd = _lowlevel.arrfunc_from_ufunc(np.negative, (np.int32,) * 2, False) myfunc.add_overload("(int16, int16) -> int16", ckd) return myfunc
def blazefunc_from_numpy_ufunc(uf, modname, name, acquires_gil): """Converts a NumPy ufunc into a Blaze ufunc. Parameters ---------- uf : NumPy ufunc The ufunc to convert. modname : str The module name to report in the ufunc's name name : str The ufunc's name. acquires_gil : bool True if the kernels in the ufunc need the GIL. TODO: should support a dict {type -> bool} to allow per-kernel control. """ # Get the list of type signatures tplist = _lowlevel.numpy_typetuples_from_ufunc(uf) tplist = _filter_tplist(tplist) siglist = [_make_sig(tp) for tp in tplist] kernlist = [_lowlevel.arrfunc_from_ufunc(uf, tp, acquires_gil) for tp in tplist] # Create the empty blaze function to start bf = ElementwiseBlazeFunc('blaze', name) # TODO: specify elementwise #bf.add_metadata({'elementwise': True}) # Add an overload to the function for each signature for (tp, sig, kern) in zip(tplist, siglist, kernlist): bf.add_overload(sig, kern) return bf
def test_lift_arrfunc(self): # First get a ckernel from numpy requiregil = False af = _lowlevel.arrfunc_from_ufunc(np.ldexp, (np.float64, np.float64, np.int32), requiregil) self.assertEqual(nd.as_py(af.proto), ndt.type("(float64, int32) -> float64")) # Now lift it af_lifted = _lowlevel.lift_arrfunc(af) self.assertEqual(nd.as_py(af_lifted.proto), ndt.type("(Dims... * float64, Dims... * int32) -> Dims... * float64")) # Create some compatible arguments in0 = nd.array([[1, 2, 3], [4, 5], [6], [7,9,10]], type='fixed * var * float64') in1 = nd.array([[-1], [10], [100], [-12]], type='fixed * 1 * int32') # Instantiate and call the kernel on these arguments out = af_lifted(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 create_overloaded_add(): # Create an overloaded blaze func, populate it with # some ckernel implementations extracted from numpy, # and test some calls on it. myfunc = ElementwiseBlazeFunc('test', 'myfunc') # overload int32 -> np.add ckd = _lowlevel.arrfunc_from_ufunc(np.add, (np.int32, np.int32, np.int32), False) myfunc.add_overload("(int32, int32) -> int32", ckd) # overload int16 -> np.subtract (so we can see the difference) ckd = _lowlevel.arrfunc_from_ufunc(np.subtract, (np.int16, np.int16, np.int16), False) myfunc.add_overload("(int16, int16) -> int16", ckd) return myfunc
def test_sum_2d_axisall(self): # Use the numpy add ufunc for this lifting test af = _lowlevel.arrfunc_from_ufunc(np.add, (np.int32, np.int32, np.int32), False) in0 = nd.array([[3, 12, -5], [10, 2, 3]]) # Simple lift sum = _lowlevel.lift_reduction_arrfunc(af, 'fixed * fixed * int32', commutative=True, associative=True) out = nd.empty(ndt.int32) sum.execute(out, in0) self.assertEqual(nd.as_py(out), 25)
def test_sum_2d_axis1(self): # Use the numpy add ufunc for this lifting test af = _lowlevel.arrfunc_from_ufunc(np.add, (np.int32, np.int32, np.int32), False) # Reduce along axis 1 sum = _lowlevel.lift_reduction_arrfunc(af, 'strided * strided * int32', axis=1, commutative=True, associative=True) in0 = nd.array([[3, 12, -5], [10, 2, 3]]) out = nd.empty(2, ndt.int32) sum.execute(out, in0) self.assertEqual(nd.as_py(out), [10, 15])
def test_sum_1d(self): # Use the numpy add ufunc for this lifting test af = _lowlevel.arrfunc_from_ufunc(np.add, (np.int32, np.int32, np.int32), False) in0 = nd.array([3, 12, -5, 10, 2]) # Simple lift sum = _lowlevel.lift_reduction_arrfunc(af, 'fixed * int32') out = nd.empty(ndt.int32) sum.execute(out, in0) self.assertEqual(nd.as_py(out), 22) # Lift with keepdims sum = _lowlevel.lift_reduction_arrfunc(af, 'fixed * int32', keepdims=True) out = nd.empty(1, ndt.int32) sum.execute(out, in0) self.assertEqual(nd.as_py(out), [22])
def check_from_numpy_int32_add(self, requiregil): # Get int32 add as an arrfunc af = _lowlevel.arrfunc_from_ufunc(np.add, (np.int32, np.int32, np.int32), requiregil) self.assertEqual(nd.as_py(af.proto), ndt.type("(int32, int32) -> int32")) a = nd.array(10, ndt.int32) b = nd.array(21, ndt.int32) c = af(a, b) self.assertEqual(nd.type_of(c), ndt.int32) self.assertEqual(nd.as_py(c), 31) af_lift = _lowlevel.lift_arrfunc(af) a = af_lift([[1], [2, 3], [4, 5, 6]], [[5, 10], [2], [1, 5, 1]]) self.assertEqual(nd.type_of(a), ndt.type('3 * var * int')) self.assertEqual(nd.as_py(a), [[6, 11], [4, 5], [5, 10, 7]])
def test_diff_op(self): # Use the numpy subtract ufunc for this lifting test af = _lowlevel.arrfunc_from_ufunc(np.subtract, (np.float64, np.float64, np.float64), False) # Lift it to 1D diff_1d = _lowlevel.lift_reduction_arrfunc(af, 'fixed * float64', axis=0, commutative=False, associative=False) # Apply it as a rolling op diff = _lowlevel.make_rolling_arrfunc(diff_1d, 2) in0 = nd.array([1.5, 3.25, 7, -3.5, 1.25]) out = diff(in0) result = nd.as_py(out) self.assertTrue(np.isnan(result[0])) self.assertEqual(result[1:], [3.25 - 1.5 , 7 - 3.25, -3.5 - 7, 1.25 - -3.5])
reductions = [ ("any", np.logical_or, False, bools), ("all", np.logical_and, True, bools), ("sum", np.add, 0, ints + floats + complexes), ("product", np.multiply, 1, ints + floats + complexes), ("min", np.minimum, None, bools + ints + floats + complexes), ("max", np.maximum, None, bools + ints + floats + complexes), ] for name, np_op, ident, types in reductions: x = ReductionBlazeFunc("blaze", name) for typ in types: x.add_overload( "(%s) -> %s" % (typ.__name__, typ.__name__), _lowlevel.arrfunc_from_ufunc(np_op, (typ,) * 3, False), associative=True, commutative=True, identity=ident, ) locals()[name] = x # ------------------------------------------------------------------------ # Other Funcs # ------------------------------------------------------------------------ rolling_mean = RollingWindowBlazeFunc("blaze", "rolling_mean") mean1d = _lowlevel.make_builtin_mean1d_arrfunc("float64", 0) rolling_mean.add_overload("(M * float64) -> M * float64", mean1d) diff = BlazeFunc("blaze", "diff")