def test_explicit_signatures(self): f = jit("(int64,int64)")(add) # Approximate match (unsafe conversion) self.assertPreciseEqual(f(1.5, 2.5), 3) self.assertEqual(len(f.overloads), 1, f.overloads) f = jit(["(int64,int64)", "(float64,float64)"])(add) # Exact signature matches self.assertPreciseEqual(f(1, 2), 3) self.assertPreciseEqual(f(1.5, 2.5), 4.0) # Approximate match (int32 -> float64 is a safe conversion) self.assertPreciseEqual(f(np.int32(1), 2.5), 3.5) # No conversion with self.assertRaises(TypeError) as cm: f(1j, 1j) self.assertIn("No matching definition", str(cm.exception)) self.assertEqual(len(f.overloads), 2, f.overloads) # A more interesting one... f = jit(["(float32,float32)", "(float64,float64)"])(add) self.assertPreciseEqual(f(np.float32(1), np.float32(2 ** -25)), 1.0) self.assertPreciseEqual(f(1, 2 ** -25), 1.0000000298023224) # Fail to resolve ambiguity between the two best overloads f = jit(["(float32,float64)", "(float64,float32)", "(int64,int64)"])(add) with self.assertRaises(TypeError) as cm: f(1.0, 2.0) # The two best matches are output in the error message, as well # as the actual argument types. self.assertRegexpMatches( str(cm.exception), r"Ambiguous overloading for <function add [^>]*> \(float64, float64\):\n" r"\(float32, float64\) -> float64\n" r"\(float64, float32\) -> float64", ) # The integer signature is not part of the best matches self.assertNotIn("int64", str(cm.exception))
def test_nrt_nested_gen(self): def gen0(arr): for i in range(arr.size): yield arr def factory(gen0): def gen1(arr): out = np.zeros_like(arr) for x in gen0(arr): out = out + x return out, arr return gen1 py_arr = np.arange(10) c_arr = py_arr.copy() py_res, py_old = factory(gen0)(py_arr) c_gen = jit(nopython=True)(factory(jit(nopython=True)(gen0))) c_res, c_old = c_gen(c_arr) self.assertIsNot(py_arr, c_arr) self.assertIs(py_old, py_arr) self.assertIs(c_old, c_arr) np.testing.assert_equal(py_res, c_res) self.assertEqual(sys.getrefcount(py_res), sys.getrefcount(c_res))
def check_inner_function_lifetime(self, **jitargs): """ When a jitted function calls into another jitted function, check that everything is collected as desired. """ def mult_10(a): return a * 10 c_mult_10 = jit('intp(intp)', **jitargs)(mult_10) c_mult_10.disable_compile() def do_math(x): return c_mult_10(x + 4) c_do_math = jit('intp(intp)', **jitargs)(do_math) c_do_math.disable_compile() self.assertEqual(c_do_math(1), 50) wrs = [weakref.ref(obj) for obj in (mult_10, c_mult_10, do_math, c_do_math, self.get_impl(c_mult_10).__self__, self.get_impl(c_do_math).__self__, )] obj = mult_10 = c_mult_10 = do_math = c_do_math = None gc.collect() self.assertEqual([w() for w in wrs], [None] * len(wrs))
def test_push_pop(self): # inspired by # https://github.com/python/cpython/blob/e42b7051/Lib/test/test_heapq.py pyfunc_heappush = heappush cfunc_heappush = jit(nopython=True)(pyfunc_heappush) pyfunc_heappop = heappop cfunc_heappop = jit(nopython=True)(pyfunc_heappop) heap = [-1.0] data = [-1.0] self.check_invariant(heap) for i in range(256): item = self.rnd.randn(1).item(0) data.append(item) cfunc_heappush(heap, item) self.check_invariant(heap) results = [] while heap: item = cfunc_heappop(heap) self.check_invariant(heap) results.append(item) data_sorted = data[:] data_sorted.sort() self.assertPreciseEqual(data_sorted, results) self.check_invariant(results)
def __init__(self, utility, dUtility, g, dG, ieqcons, dIeqcons, la, ua, idx , beta=0.95, mu = [(0,1)]): super(DynamicModelSLSQP, self).__init__(utility, g, la, ua, idx , beta, mu ) self.dUtility = jit(dUtility) self.dG = jit(dG) self.ieqcons = jit(ieqcons) self.dIeqcons = jit(dIeqcons)
def make_apply_function(func, out_args, in_args, parameters, do_jit=True, **kwargs): """ Takes a '_calc' function and creates the necessary Python code for an _apply style function. Will also jit the function if desired Parameters ---------- func: the 'calc' style function out_args: list of out arguments for the apply function in_args: list of in arguments for the apply function parameters: iterable of which of the args (from in_args) are parameter variables (as opposed to column records). This influences how we construct the '_apply' function do_jit: Bool, if True, jit the resulting apply function Returns ------- '_apply' style function """ jitted_f = jit(**kwargs)(func) apfunc = create_apply_function_string(out_args, in_args, parameters) func_code = compile(apfunc, "<string>", "exec") fakeglobals = {} eval(func_code, {"jitted_f": jitted_f}, fakeglobals) if do_jit: return jit(**kwargs)(fakeglobals['ap_func']) else: return fakeglobals['ap_func']
def test_reflection_of_mutable_container(self): # tests that reflection in list/set warns def foo_list(a): return a.append(1) def foo_set(a): return a.add(1) for f in [foo_list, foo_set]: container = f.__name__.strip('foo_') inp = eval(container)([10, ]) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("ignore", category=NumbaWarning) warnings.simplefilter("always", category=NumbaPendingDeprecationWarning) jit(nopython=True)(f)(inp) self.assertEqual(len(w), 1) self.assertEqual(w[0].category, NumbaPendingDeprecationWarning) warn_msg = str(w[0].message) msg = ("Encountered the use of a type that is scheduled for " "deprecation") self.assertIn(msg, warn_msg) msg = ("\'reflected %s\' found for argument" % container) self.assertIn(msg, warn_msg) self.assertIn("http://numba.pydata.org", warn_msg)
def check_consume_generator(self, gen_func): cgen = jit(nopython=True)(gen_func) cfunc = jit(nopython=True)(make_consumer(cgen)) pyfunc = make_consumer(gen_func) expected = pyfunc(5) got = cfunc(5) self.assertPreciseEqual(got, expected)
def compiled(self): # Compile it if this is the first time. if (not hasattr(self, '_compiled')) and NUMBA_AVAILABLE: if self.jit_kwargs is not None: self._compiled = numba.jit(**self.jit_kwargs)(self.func) else: self._compiled = numba.jit(self.func) return self._compiled
def test_func1(self): pyfunc = call_func1_nullary cfunc = jit(nopython=True)(pyfunc) self.assertPreciseEqual(cfunc(), 42) pyfunc = call_func1_unary cfunc = jit(nopython=True)(pyfunc) self.assertPreciseEqual(cfunc(None), 42) self.assertPreciseEqual(cfunc(18.0), 6.0)
def test_np_take(self): # shorter version of array.take test in test_array_methods pyfunc = np_take cfunc = jit(nopython=True)(pyfunc) def check(arr, ind): expected = pyfunc(arr, ind) got = cfunc(arr, ind) self.assertPreciseEqual(expected, got) if hasattr(expected, 'order'): self.assertEqual(expected.order == got.order) # need to check: # 1. scalar index # 2. 1d array index # 3. nd array index # 4. reflected list # 5. tuples test_indices = [] test_indices.append(1) test_indices.append(np.array([1, 5, 1, 11, 3])) test_indices.append(np.array([[[1], [5]], [[1], [11]]])) test_indices.append([1, 5, 1, 11, 3]) test_indices.append((1, 5, 1)) test_indices.append(((1, 5, 1), (11, 3, 2))) for dt in [np.int64, np.complex128]: A = np.arange(12, dtype=dt).reshape((4, 3)) for ind in test_indices: check(A, ind) #check illegal access raises szA = A.size illegal_indices = [szA, -szA - 1, np.array(szA), np.array(-szA - 1), [szA], [-szA - 1]] for x in illegal_indices: with self.assertRaises(IndexError): cfunc(A, x) # oob raises # check float indexing raises with self.assertRaises(TypingError): cfunc(A, [1.7]) # check unsupported arg raises with self.assertRaises(TypingError): take_kws = jit(nopython=True)(np_take_kws) take_kws(A, 1, 1) # check kwarg unsupported raises with self.assertRaises(TypingError): take_kws = jit(nopython=True)(np_take_kws) take_kws(A, 1, axis=1) #exceptions leak refs self.disable_leak_check()
def check_dot_mm(self, pyfunc2, pyfunc3, func_name): def samples(m, n, k): for order_a, order_b in product('CF', 'CF'): a = self.sample_matrix(m, k, np.float64).copy(order=order_a) b = self.sample_matrix(k, n, np.float64).copy(order=order_b) yield a, b for dtype in self.dtypes: a = self.sample_matrix(m, k, dtype) b = self.sample_matrix(k, n, dtype) yield a, b # Non-contiguous yield a[::-1], b[::-1] cfunc2 = jit(nopython=True)(pyfunc2) if pyfunc3 is not None: cfunc3 = jit(nopython=True)(pyfunc3) # Test generic matrix * matrix as well as "degenerate" cases # where one of the outer dimensions is 1 (i.e. really represents # a vector, which may select a different implementation) for m, n, k in [(2, 3, 4), # Generic matrix * matrix (1, 3, 4), # 2d vector * matrix (1, 1, 4), # 2d vector * 2d vector ]: for a, b in samples(m, n, k): self.check_func(pyfunc2, cfunc2, (a, b)) self.check_func(pyfunc2, cfunc2, (b.T, a.T)) if pyfunc3 is not None: for a, b in samples(m, n, k): out = np.empty((m, n), dtype=a.dtype) self.check_func_out(pyfunc3, cfunc3, (a, b), out) out = np.empty((n, m), dtype=a.dtype) self.check_func_out(pyfunc3, cfunc3, (b.T, a.T), out) # Mismatching sizes m, n, k = 2, 3, 4 a = self.sample_matrix(m, k - 1, np.float64) b = self.sample_matrix(k, n, np.float64) self.assert_mismatching_sizes(cfunc2, (a, b)) if pyfunc3 is not None: out = np.empty((m, n), np.float64) self.assert_mismatching_sizes(cfunc3, (a, b, out)) a = self.sample_matrix(m, k, np.float64) b = self.sample_matrix(k, n, np.float64) out = np.empty((m, n - 1), np.float64) self.assert_mismatching_sizes(cfunc3, (a, b, out), is_out=True) # Mismatching dtypes a = self.sample_matrix(m, k, np.float32) b = self.sample_matrix(k, n, np.float64) self.assert_mismatching_dtypes(cfunc2, (a, b), func_name) if pyfunc3 is not None: a = self.sample_matrix(m, k, np.float64) b = self.sample_matrix(k, n, np.float64) out = np.empty((m, n), np.float32) self.assert_mismatching_dtypes(cfunc3, (a, b, out), func_name)
def test_negative_to_unsigned(self): def f(x): return x # TypeError is for 2.6 if sys.version_info >= (2, 7): with self.assertRaises(OverflowError): jit('uintp(uintp)', nopython=True)(f)(-5) else: with self.assertRaises(TypeError): jit('uintp(uintp)', nopython=True)(f)(-5)
def test_bar_call_foo_compiled_twice(self): # When a function is compiled twice, then called from another # compiled function, check that the right target is called. # (otherwise, LLVM would assert out or crash) global cfoo for i in range(2): cfoo = jit((int32, int32), nopython=True)(foo) gc.collect() cbar = jit((int32, int32), nopython=True)(bar) self.assertEqual(cbar(1, 2), 1 + 2 + 2)
def test_from_buffer_struct(self): n = 10 x = np.arange(n) + np.arange(n * 2, n * 3) * 1j y = np.zeros(n) real_cfunc = jit(nopython=True)(mod.vector_extract_real) real_cfunc(x, y) np.testing.assert_equal(x.real, y) imag_cfunc = jit(nopython=True)(mod.vector_extract_imag) imag_cfunc(x, y) np.testing.assert_equal(x.imag, y)
def test_sum_1d_kws(self): # check 1d reduces to scalar pyfunc = array_sum_kws cfunc = jit(nopython=True)(pyfunc) a = np.arange(10.) self.assertPreciseEqual(pyfunc(a, axis=0), cfunc(a, axis=0)) pyfunc = array_sum_const_axis_neg_one cfunc = jit(nopython=True)(pyfunc) a = np.arange(10.) self.assertPreciseEqual(pyfunc(a, axis=-1), cfunc(a, axis=-1))
def test_exception(self): unsafe_foo = jit(target='cuda')(foo) safe_foo = jit(target='cuda', debug=True)(foo) if not config.ENABLE_CUDASIM: # Simulator throws exceptions regardless of debug # setting unsafe_foo[1, 2](numpy.array([0,1])) with self.assertRaises(IndexError) as cm: safe_foo[1, 2](numpy.array([0,1])) self.assertIn("tuple index out of range", str(cm.exception))
def test_constructor(self): pyfunc = empty_constructor_usecase cfunc = jit(nopython=True)(pyfunc) self.assertPreciseEqual(cfunc(), pyfunc()) pyfunc = constructor_usecase cfunc = jit(nopython=True)(pyfunc) def check(arg): self.assertPreciseEqual(pyfunc(arg), cfunc(arg)) check(self.duplicates_array(200)) check(self.sparse_array(200))
def test_exception(self): unsafe_foo = jit(target='cuda')(foo) safe_foo = jit(target='cuda', debug=True)(foo) unsafe_foo[1, 2](numpy.array([0,1])) try: safe_foo[1, 2](numpy.array([0,1])) except cuda.KernelRuntimeError as e: print("error raised as expected:\n%s" % e) else: raise AssertionError("expecting an exception")
def test_neq(self): def test_impl1(): s = 'test' return s != 'test' def test_impl2(): s = 'test1' return s != 'test' cfunc1 = jit(nopython=True)(test_impl1) cfunc2 = jit(nopython=True)(test_impl2) self.assertEqual(test_impl1(), cfunc1()) self.assertEqual(test_impl2(), cfunc2())
def check_raise_nested(self, flags, **jit_args): """ Check exception propagation from nested functions. """ for clazz in [MyError, UDEArgsToSuper, UDENoArgSuper]: inner_pyfunc = raise_instance(clazz, "some message") pyfunc = outer_function(inner_pyfunc) inner_cfunc = jit(**jit_args)(inner_pyfunc) cfunc = jit(**jit_args)(outer_function(inner_cfunc)) self.check_against_python(flags, pyfunc, cfunc, clazz, 1) self.check_against_python(flags, pyfunc, cfunc, ValueError, 2) self.check_against_python(flags, pyfunc, cfunc, OtherError, 3)
def test_cumsum(self): pyfunc = array_cumsum cfunc = jit(nopython=True)(pyfunc) # OK a = np.ones((2, 3)) self.assertPreciseEqual(pyfunc(a), cfunc(a)) # BAD: with axis with self.assertRaises(TypingError): cfunc(a, 1) # BAD: with kw axis pyfunc = array_cumsum_kws cfunc = jit(nopython=True)(pyfunc) with self.assertRaises(TypingError): cfunc(a, axis=1)
def test_print_vararg(self): # Test *args support for print(). This is desired since # print() can use a dedicated IR node. pyfunc = print_vararg cfunc = jit(nopython=True)(pyfunc) with captured_stdout(): cfunc(1, (2, 3), (4, 5j)) self.assertEqual(sys.stdout.getvalue(), '1 (2, 3) 4 5j\n') pyfunc = print_string_vararg cfunc = jit(nopython=True)(pyfunc) with captured_stdout(): cfunc(1, (2, 3), (4, 5j)) self.assertEqual(sys.stdout.getvalue(), '1 hop! (2, 3) 4 5j\n')
def test_jitfallback(self): # tests that @jit falling back to object mode raises a # NumbaDeprecationWarning with warnings.catch_warnings(record=True) as w: warnings.simplefilter("ignore", category=NumbaWarning) warnings.simplefilter("always", category=NumbaDeprecationWarning) def foo(): return [] # empty list cannot be typed jit(foo)() msg = ("Fall-back from the nopython compilation path to the object " "mode compilation path") self.check_warning(w, msg, NumbaDeprecationWarning)
def test_array_dot(self): # just ensure that the dot impl dispatches correctly, do # not test dot itself, this is done in test_linalg. pyfunc = array_dot cfunc = jit(nopython=True)(pyfunc) a = np.arange(20.).reshape(4, 5) b = np.arange(5.) np.testing.assert_equal(pyfunc(a, b), cfunc(a, b)) # check that chaining works pyfunc = array_dot_chain cfunc = jit(nopython=True)(pyfunc) a = np.arange(16.).reshape(4, 4) np.testing.assert_equal(pyfunc(a, a), cfunc(a, a))
def check_dot_vm(self, pyfunc2, pyfunc3, func_name): m, n = 2, 3 def samples(m, n): for order in 'CF': a = self.sample_matrix(m, n, np.float64).copy(order=order) b = self.sample_vector(n, np.float64) yield a, b for dtype in self.dtypes: a = self.sample_matrix(m, n, dtype) b = self.sample_vector(n, dtype) yield a, b # Non-contiguous yield a[::-1], b[::-1] cfunc2 = jit(nopython=True)(pyfunc2) if pyfunc3 is not None: cfunc3 = jit(nopython=True)(pyfunc3) for a, b in samples(m, n): self.check_func(pyfunc2, cfunc2, (a, b)) self.check_func(pyfunc2, cfunc2, (b, a.T)) if pyfunc3 is not None: for a, b in samples(m, n): out = np.empty(m, dtype=a.dtype) self.check_func_out(pyfunc3, cfunc3, (a, b), out) self.check_func_out(pyfunc3, cfunc3, (b, a.T), out) # Mismatching sizes a = self.sample_matrix(m, n - 1, np.float64) b = self.sample_vector(n, np.float64) self.assert_mismatching_sizes(cfunc2, (a, b)) self.assert_mismatching_sizes(cfunc2, (b, a.T)) if pyfunc3 is not None: out = np.empty(m, np.float64) self.assert_mismatching_sizes(cfunc3, (a, b, out)) self.assert_mismatching_sizes(cfunc3, (b, a.T, out)) a = self.sample_matrix(m, m, np.float64) b = self.sample_vector(m, np.float64) out = np.empty(m - 1, np.float64) self.assert_mismatching_sizes(cfunc3, (a, b, out), is_out=True) self.assert_mismatching_sizes(cfunc3, (b, a.T, out), is_out=True) # Mismatching dtypes a = self.sample_matrix(m, n, np.float32) b = self.sample_vector(n, np.float64) self.assert_mismatching_dtypes(cfunc2, (a, b), func_name) if pyfunc3 is not None: a = self.sample_matrix(m, n, np.float64) b = self.sample_vector(n, np.float64) out = np.empty(m, np.float32) self.assert_mismatching_dtypes(cfunc3, (a, b, out), func_name)
def test_nbest(self): # inspired by # https://github.com/python/cpython/blob/e42b7051/Lib/test/test_heapq.py cfunc_heapify = jit(nopython=True)(heapify) cfunc_heapreplace = jit(nopython=True)(heapreplace) data = self.rnd.choice(range(2000), 1000).tolist() heap = data[:10] cfunc_heapify(heap) for item in data[10:]: if item > heap[0]: cfunc_heapreplace(heap, item) self.assertPreciseEqual(list(self.heapiter(heap)), sorted(data)[-10:])
def run_jit_inner_function(self, **jitargs): def mult_10(a): return a * 10 c_mult_10 = jit('intp(intp)', **jitargs)(mult_10) c_mult_10.disable_compile() def do_math(x): return c_mult_10(x + 4) c_do_math = jit('intp(intp)', **jitargs)(do_math) c_do_math.disable_compile() with self.assertRefCount(c_do_math, c_mult_10): self.assertEqual(c_do_math(1), 50)
def make_wrapper(func): theargs = inspect.getargspec(func).args jitted_f = jit(**kwargs)(func) jitted_apply = make_apply_function(func, dtype_sig_out, dtype_sig_in, parameters, **kwargs) def wrapper(*args, **kwargs): in_arrays = [] out_arrays = [] for farg in theargs: if hasattr(args[0], farg): in_arrays.append(getattr(args[0], farg)) else: in_arrays.append(getattr(args[1], farg)) for farg in dtype_sig_out: if hasattr(args[0], farg): out_arrays.append(getattr(args[0], farg)) else: out_arrays.append(getattr(args[1], farg)) final_array = out_arrays + in_arrays ans = jitted_apply(*final_array) return ans return wrapper
def test_nrt_nested_nopython_gen(self): """ Test nesting three generators """ def factory(decor=lambda x: x): @decor def foo(a, n): for i in range(n): yield a[i] a[i] += i @decor def bar(n): a = np.arange(n) for i in foo(a, n): yield i * 2 for i in range(a.size): yield a[i] @decor def cat(n): for i in bar(n): yield i + i return cat py_gen = factory() c_gen = factory(jit(nopython=True)) py_res = list(py_gen(10)) c_res = list(c_gen(10)) self.assertEqual(py_res, c_res)
def check(const): pyfunc = make_add_constant(const) f = jit(nopython=True)(pyfunc) x = TD(4, 'D') expected = pyfunc(x) self.assertPreciseEqual(f(x), expected)
def jit(self, pyfunc): return jit(**self.jitargs)(pyfunc)
def test_timedelta(self, **jitargs): eq = jit(**jitargs)(eq_usecase) self.assertTrue(eq(TD(2, '10Y'), TD(20, 'Y')))
def test_nlargest_exceptions(self): pyfunc = nlargest cfunc = jit(nopython=True)(pyfunc) self._assert_typing_error(cfunc)
def _jit_func(self): vectorize = numba.jit(self.signature, nopython=True) return vectorize(self.func)
def test_index1(self): self.disable_leak_check() pyfunc = list_index1 cfunc = jit(nopython=True)(pyfunc) for v in (0, 1, 5, 10, 99999999): self.check_index_result(pyfunc, cfunc, (16, v))
def check_add(self, pyfunc): cfunc = jit(nopython=True)(pyfunc) sizes = [0, 3, 50, 300] for m, n in itertools.product(sizes, sizes): expected = pyfunc(m, n) self.assertPreciseEqual(cfunc(m, n), expected)
def _weighted_sum(matrices, weights, target, normalize): if target is None: target = matrices[0].copy() else: target.data.values[:] = matrices[0].data.values v = target.data.values * weights[0] for w, m in zip(weights[1:], matrices[1:]): v[:] += w * m.data.values target.data.values[:] = v if normalize: target.normalize_preferences() return target if _use_numba: _weighted_sum = nb.jit()(_weighted_sum) class PreferenceMatrix(object): def __init__(self, ranking, axiom_name): sr = ranking self._data = pd.DataFrame(data=np.zeros((len(sr), len(sr)), dtype=np.float64), columns=sr, index=sr) self._axiom = axiom_name def __repr__(self, *args, **kwargs): return self._data.__repr__(*args, **kwargs) @property
def test_four_level(self): pfunc = self.mod.make_four_level() cfunc = self.mod.make_four_level(jit(nopython=True)) arg = 7 self.assertPreciseEqual(pfunc(arg), cfunc(arg))
def test_type_change(self): pfunc = self.mod.make_type_change_mutual() cfunc = self.mod.make_type_change_mutual(jit(nopython=True)) args = 13, 0.125 self.assertPreciseEqual(pfunc(*args), cfunc(*args))
def test_mutual_2(self): pfoo, pbar = self.mod.make_mutual2() cfoo, cbar = self.mod.make_mutual2(jit(nopython=True)) for x in [-1, 0, 1, 3]: self.assertPreciseEqual(pfoo(x=x), cfoo(x=x)) self.assertPreciseEqual(pbar(y=x, z=1), cbar(y=x, z=1))
import numba import numpy as np myjit = numba.jit(nopython=True, cache=True) @myjit def dPhi(phi1, phi2): dphi = np.abs(phi2 - phi1) if dphi >= np.pi: dphi -= 2.0 * np.pi if dphi < -np.pi: dphi += 2.0 * np.pi return dphi @myjit def deltaR(eta1, phi1, eta2, phi2): dphi = dPhi(phi1, phi2) deta = eta2 - eta1 return (deta * deta + dphi * dphi)**0.5 @myjit def transverse_mass(pt1, phi1, pt2, phi2): return (2.0 * pt1 * pt2 * (1 - np.cos(phi1 - phi2)))**0.5 @myjit def invariant_mass(pt1, eta1, phi1, mass1, pt2, eta2, phi2, mass2): px1 = pt1 * np.cos(phi1) px2 = pt2 * np.cos(phi2) py1 = pt1 * np.sin(phi1)
class TestObjmodeFallback(TestCase): # These are all based on tests from real life issues where, predominantly, # the object mode fallback compilation path would fail as a result of the IR # being mutated by closure inlining in npm. Tests are named after issues, # all of which failed to compile as of 0.44. decorators = [jit, jit(forceobj=True)] def test_issue2955(self): def numbaFailure(scores, cooc): rows, cols = scores.shape for i in range(rows): coxv = scores[i] groups = sorted(set(coxv), reverse=True) [set(np.argwhere(coxv == x).flatten()) for x in groups] x = np.random.random((10, 10)) y = np.abs((np.random.randn(10, 10) * 1.732)).astype(np.int) for d in self.decorators: d(numbaFailure)(x, y) def test_issue3239(self): def fit(X, y): if type(X) is not np.ndarray: X = np.array(X) if type(y) is not np.ndarray: y = np.array(y) m, _ = X.shape X = np.hstack((np.array([[1] for _ in range(m)]), X)) res = np.dot(np.dot(X, X.T), y) intercept = res[0] coefs = res[1:] return intercept, coefs for d in self.decorators: res = d(fit)(np.arange(10).reshape(1, 10), np.arange(10).reshape(1, 10)) exp = fit( np.arange(10).reshape(1, 10), np.arange(10).reshape(1, 10)) np.testing.assert_equal(res, exp) def test_issue3289(self): b = [(5, 124), (52, 5)] def a(): [b[index] for index in [0, 1]] for x in range(5): pass for d in self.decorators: d(a)() def test_issue3413(self): def foo(data): # commenting out this line prevents the crash: t = max([len(m) for m in data['y']]) mask = data['x'] == 0 if any(mask): z = 15 return t, z data = {'x': np.arange(5), 'y': [[1], [2, 3]]} for d in self.decorators: res = d(foo)(data) np.testing.assert_allclose(res, foo(data)) def test_issue3659(self): def main(): a = np.array(((1, 2), (3, 4))) return np.array([x for x in a]) for d in self.decorators: res = d(main)() np.testing.assert_allclose(res, main()) def test_issue3803(self): def center(X): np.array([np.float_(x) for x in X.T]) np.array([np.float_(1) for _ in X.T]) return X X = np.zeros((10, )) for d in self.decorators: res = d(center)(X) np.testing.assert_allclose(res, center(X))
def test_identity(self): pyfunc = identity_usecase cfunc = jit(nopython=True)(pyfunc) self.assertPreciseEqual(cfunc(3), pyfunc(3))
def test_add_inplace_heterogenous(self): pyfunc = list_add_inplace_heterogenous cfunc = jit(nopython=True)(pyfunc) expected = pyfunc() self.assertEqual(cfunc(), expected)
def test_from_buffer_pyarray(self): pyfunc = mod.vector_sin_float32 cfunc = jit(nopython=True)(pyfunc) x = array.array("f", range(10)) y = array.array("f", [0] * len(x)) self.check_vector_sin(cfunc, x, y)
def test_count(self): pyfunc = list_count cfunc = jit(nopython=True)(pyfunc) for v in range(5): self.assertPreciseEqual(cfunc(18, v), pyfunc(18, v))
def test_user_defined_symbols(self): pyfunc = mod.use_user_defined_symbols cfunc = jit(nopython=True)(pyfunc) self.assertEqual(pyfunc(), cfunc())
def check_unary_with_size(self, pyfunc, precise=True): cfunc = jit(nopython=True)(pyfunc) # Use various sizes, to stress the allocation algorithm for n in [0, 3, 16, 70, 400]: eq = self.assertPreciseEqual if precise else self.assertEqual eq(cfunc(n), pyfunc(n))
def _test_from_buffer_numpy_array(self, pyfunc, dtype): x = np.arange(10).astype(dtype) y = np.zeros_like(x) cfunc = jit(nopython=True)(pyfunc) self.check_vector_sin(cfunc, x, y)
def test_take(self): pyfunc = array_take cfunc = jit(nopython=True)(pyfunc) def check(arr, ind): expected = pyfunc(arr, ind) got = cfunc(arr, ind) self.assertPreciseEqual(expected, got) if hasattr(expected, 'order'): self.assertEqual(expected.order == got.order) # need to check: # 1. scalar index # 2. 1d array index # 3. nd array index, >2d and F order # 4. reflected list # 5. tuples test_indices = [] test_indices.append(1) test_indices.append(5) test_indices.append(11) test_indices.append(-2) test_indices.append(np.array([1, 5, 1, 11, 3])) test_indices.append(np.array([[1, 5, 1], [11, 3, 0]], order='F')) test_indices.append(np.array([[[1, 5, 1], [11, 3, 0]]])) test_indices.append(np.array([[[[1, 5]], [[11, 0]], [[1, 2]]]])) test_indices.append([1, 5, 1, 11, 3]) test_indices.append((1, 5, 1)) test_indices.append(((1, 5, 1), (11, 3, 2))) test_indices.append((((1,), (5,), (1,)), ((11,), (3,), (2,)))) layouts = cycle(['C', 'F', 'A']) for dt in [np.float64, np.int64, np.complex128]: A = np.arange(12, dtype=dt).reshape((4, 3), order=next(layouts)) for ind in test_indices: check(A, ind) #check illegal access raises A = np.arange(12, dtype=dt).reshape((4, 3), order=next(layouts)) szA = A.size illegal_indices = [szA, -szA - 1, np.array(szA), np.array(-szA - 1), [szA], [-szA - 1]] for x in illegal_indices: with self.assertRaises(IndexError): cfunc(A, x) # oob raises # check float indexing raises with self.assertRaises(TypingError): cfunc(A, [1.7]) # check unsupported arg raises with self.assertRaises(TypingError): take_kws = jit(nopython=True)(array_take_kws) take_kws(A, 1, 1) # check kwarg unsupported raises with self.assertRaises(TypingError): take_kws = jit(nopython=True)(array_take_kws) take_kws(A, 1, axis=1) #exceptions leak refs self.disable_leak_check()
jit = jitclass = dummy_decorator # for jitclass spec... if spec could be lazy evaluated, wouldn't need class dummy: def __getitem__(self, _): return None def __getattr__(self, _): return dummy() numba = dummy() from .pattern import Vars from .graphics import Layer, Points njit = jit(nopython=True, fastmath=True) # import llvmlite.binding as llvm # llvm.set_option('', '--debug-only=loop-vectorize') @njit def lerp(a, b, m): return a * (1 - m) + b * m @njit def interp2d(a, p): """interpolating ndarray access""" x_lo, x_m = divmod(p[0], 1) y_lo, y_m = divmod(p[1], 1) a = a[x_lo:x_lo + 2, y_lo:y_lo + 2]
def partial_inner(func): return jit(func)
def test_range_unify(self): pyfunc = range_unify_usecase cfunc = jit(nopython=True)(pyfunc) for v in (0, 1): res = cfunc(v) self.assertPreciseEqual(res, pyfunc(v))
def test_datetime(self, **jitargs): eq = jit(**jitargs)(eq_usecase) self.assertTrue(eq(DT('2014', '10Y'), DT('2010')))
def test_issue_1394(self): pyfunc = issue_1394 cfunc = jit(nopython=True)(pyfunc) for v in (0, 1, 2): res = cfunc(v) self.assertEqual(res, pyfunc(v))
def test_bool(self): pyfunc = list_bool cfunc = jit(nopython=True)(pyfunc) for n in [0, 1, 3]: expected = pyfunc(n) self.assertPreciseEqual(cfunc(n), expected)
def check_mul(self, pyfunc): cfunc = jit(nopython=True)(pyfunc) for n in [0, 3, 50, 300]: for v in [1, 2, 3, 0, -1, -42]: expected = pyfunc(n, v) self.assertPreciseEqual(cfunc(n, v), expected)
def test_bulk_use_cases(self): """ Tests the large number of use cases defined below """ # jitted function used in some tests @njit def fib3(n): if n < 2: return n return fib3(n - 1) + fib3(n - 2) def outer1(x): """ Test calling recursive function from inner """ def inner(x): return fib3(x) return inner(x) def outer2(x): """ Test calling recursive function from closure """ z = x + 1 def inner(x): return x + fib3(z) return inner(x) def outer3(x): """ Test recursive inner """ def inner(x): if x < 2: return 10 else: inner(x - 1) return inner(x) def outer4(x): """ Test recursive closure """ y = x + 1 def inner(x): if x + y < 2: return 10 else: inner(x - 1) return inner(x) def outer5(x): """ Test nested closure """ y = x + 1 def inner1(x): z = y + x + 2 def inner2(x): return x + z return inner2(x) + y return inner1(x) def outer6(x): """ Test closure with list comprehension in body """ y = x + 1 def inner1(x): z = y + x + 2 return [t for t in range(z)] return inner1(x) _OUTER_SCOPE_VAR = 9 def outer7(x): """ Test use of outer scope var, no closure """ z = x + 1 return x + z + _OUTER_SCOPE_VAR _OUTER_SCOPE_VAR = 9 def outer8(x): """ Test use of outer scope var, with closure """ z = x + 1 def inner(x): return x + z + _OUTER_SCOPE_VAR return inner(x) def outer9(x): """ Test closure assignment""" z = x + 1 def inner(x): return x + z f = inner return f(x) def outer10(x): """ Test two inner, one calls other """ z = x + 1 def inner(x): return x + z def inner2(x): return inner(x) return inner2(x) def outer11(x): """ return the closure """ z = x + 1 def inner(x): return x + z return inner def outer12(x): """ closure with kwarg""" z = x + 1 def inner(x, kw=7): return x + z + kw return inner(x) def outer13(x, kw=7): """ outer with kwarg no closure""" z = x + 1 + kw return z def outer14(x, kw=7): """ outer with kwarg used in closure""" z = x + 1 def inner(x): return x + z + kw return inner(x) def outer15(x, kw=7): """ outer with kwarg as arg to closure""" z = x + 1 def inner(x, kw): return x + z + kw return inner(x, kw) def outer16(x): """ closure is generator, consumed locally """ z = x + 1 def inner(x): yield x + z return list(inner(x)) def outer17(x): """ closure is generator, returned """ z = x + 1 def inner(x): yield x + z return inner(x) def outer18(x): """ closure is generator, consumed in loop """ z = x + 1 def inner(x): yield x + z for i in inner(x): t = i return t def outer19(x): """ closure as arg to another closure """ z1 = x + 1 z2 = x + 2 def inner(x): return x + z1 def inner2(f, x): return f(x) + z2 return inner2(inner, x) def outer20(x): #""" Test calling numpy in closure """ z = x + 1 def inner(x): return x + numpy.cos(z) return inner(x) def outer21(x): #""" Test calling numpy import as in closure """ z = x + 1 def inner(x): return x + np.cos(z) return inner(x) # functions to test that are expected to pass f = [ outer1, outer2, outer5, outer6, outer7, outer8, outer9, outer10, outer12, outer13, outer14, outer15, outer19, outer20, outer21 ] for ref in f: cfunc = njit(ref) var = 10 self.assertEqual(cfunc(var), ref(var)) # test functions that are expected to fail with self.assertRaises(NotImplementedError) as raises: cfunc = jit(nopython=True)(outer3) cfunc(var) msg = "Unsupported use of op_LOAD_CLOSURE encountered" self.assertIn(msg, str(raises.exception)) with self.assertRaises(NotImplementedError) as raises: cfunc = jit(nopython=True)(outer4) cfunc(var) msg = "Unsupported use of op_LOAD_CLOSURE encountered" self.assertIn(msg, str(raises.exception)) with self.assertRaises(TypingError) as raises: cfunc = jit(nopython=True)(outer11) cfunc(var) msg = "Cannot capture the non-constant value" self.assertIn(msg, str(raises.exception)) with self.assertRaises(UnsupportedError) as raises: cfunc = jit(nopython=True)(outer16) cfunc(var) msg = "The use of yield in a closure is unsupported." self.assertIn(msg, str(raises.exception)) with self.assertRaises(UnsupportedError) as raises: cfunc = jit(nopython=True)(outer17) cfunc(var) msg = "The use of yield in a closure is unsupported." self.assertIn(msg, str(raises.exception)) with self.assertRaises(UnsupportedError) as raises: cfunc = jit(nopython=True)(outer18) cfunc(var) msg = "The use of yield in a closure is unsupported." self.assertIn(msg, str(raises.exception))
def test_bool_list(self): # Check lists of bools compile and run successfully pyfunc = bool_list_usecase cfunc = jit(nopython=True)(pyfunc) self.assertPreciseEqual(cfunc(), pyfunc())