def test_empty_givens_updates(): # Regression test for bug fixed in 8625e03. # Empty givens / updates dictionaries were not properly detected before, # triggering useless crashes at compile time. x = tt.scalar() y = x * 2 function([aesara.In(x)], y, givens={}) function([aesara.In(x)], y, updates={})
def test_input_aliasing_affecting_inplace_operations(self): # Note: to trigger this bug with aesara rev 4586:2bc6fc7f218b, # you need to make in inputs mutable (so that inplace # operations are used) and to break the elemwise composition # with some non-elemwise op (here dot) x = aesara.tensor.dvector() y = aesara.tensor.dvector() m1 = aesara.tensor.dmatrix() m2 = aesara.tensor.dmatrix() f = aesara.function( [ aesara.In(x, mutable=True), aesara.In(y, mutable=True), aesara.In(m1, mutable=True), aesara.In(m2, mutable=True), ], aesara.dot((x * 2), m1) + aesara.dot((y * 3), m2), ) # Test 1. If the same variable is given twice # Compute bogus values v = np.asarray([1, 2, 3, 4, 5], dtype="float64") m = np.asarray( [ [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1], ], dtype="float64", ) bogus_vals = f(v, v, m, m) # Since we used inplace operation v and m may be corrupted # so we need to recreate them v = np.asarray([1, 2, 3, 4, 5], dtype="float64") m = np.asarray( [ [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1], ], dtype="float64", ) m_copy = m.copy() v_copy = v.copy() vals = f(v, v_copy, m, m_copy) assert np.allclose(vals, bogus_vals)
def test_default_values(self): # Check that default values are restored # when an exception occurs in interactive mode. a, b = tt.dscalars("a", "b") c = a + b func = aesara.function( [aesara.In(a, name="first"), aesara.In(b, value=1, name="second")], c ) x = func(first=1) try: func(second=2) except TypeError: assert func(first=1) == x
def test_sparse_input_aliasing_affecting_inplace_operations(self): sp = pytest.importorskip("scipy", minversion="0.7.0") from aesara import sparse # Note: to trigger this bug with aesara rev 4586:2bc6fc7f218b, # you need to make in inputs mutable (so that inplace # operations are used) and to break the elemwise composition # with some non-elemwise op (here dot) x = sparse.SparseType("csc", dtype="float64")() y = sparse.SparseType("csc", dtype="float64")() f = aesara.function( [aesara.In(x, mutable=True), aesara.In(y, mutable=True)], (x + y) + (x + y)) # Test 1. If the same variable is given twice # Compute bogus values m = sp.sparse.csc_matrix( np.asarray( [ [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1], ], dtype="float64", )) bogus_vals = f(m, m) # Since we used inplace operation v and m may be corrupted # so we need to recreate them m = sp.sparse.csc_matrix( np.asarray( [ [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1], ], dtype="float64", )) m_copy = m.copy() vals = f(m, m_copy) assert np.allclose(vals.todense(), bogus_vals.todense())
def test_check_for_aliased_inputs(self): b = np.random.rand(5, 4) s1 = aesara.shared(b) s2 = aesara.shared(b) x1 = tt.vector() # Assert cases we should not check for aliased inputs for d in [ dict(outputs=[s1 + 1]), dict(outputs=[s1 + 1, s2 + 3]), dict(outputs=[s1 + 1], updates=[(s2, s2 + 3)]), dict(inputs=[x1], outputs=[x1 + 1], updates=[(s2, s2 + 3)]), ]: if "inputs" not in d: d["inputs"] = [] f = aesara.function(**d) assert not f._check_for_aliased_inputs, d # Assert cases we should check for aliased inputs for d in [ dict( inputs=[aesara.In(x1, borrow=True)], outputs=[x1 + 1], updates=[(s2, s2 + 3)], ), dict( inputs=[aesara.In(x1, borrow=True, mutable=True)], outputs=[x1 + 1], updates=[(s2, s2 + 3)], ), dict( inputs=[aesara.In(x1, mutable=True)], outputs=[x1 + 1], updates=[(s2, s2 + 3)], ), ]: if "inputs" not in d: d["inputs"] = [] f = aesara.function(**d) assert f._check_for_aliased_inputs, d
def test_vm_gc(): # This already caused a bug in the trunk of Aesara. # # The bug was introduced in the trunk on July 5th, 2012 and fixed on # July 30th. x = aesara.tensor.vector() p = RunOnce()(x) mode = aesara.Mode(linker=aesara.gof.vm.VM_Linker(lazy=True)) f = aesara.function([aesara.In(x, mutable=True)], [p + 1, p + 2], mode=mode) f([1, 2, 3]) p = RunOnce()(x) pp = p + p f = aesara.function([x], [pp + pp], mode=mode) f([1, 2, 3])
def test_partial_input_aliasing_affecting_inplace_operations(self): # Note: to trigger this bug with aesara rev 4586:2bc6fc7f218b, # you need to make in inputs mutable ( so that inplace # operations are used) and to break the elemwise composition # with some non-elemwise op ( here dot ) x = aesara.tensor.dvector() y = aesara.tensor.dvector() z = aesara.tensor.dvector() m1 = aesara.tensor.dmatrix() m2 = aesara.tensor.dmatrix() m3 = aesara.tensor.dmatrix() # Test 2. If variables only partial overlap # more exactly we care about the case when we have a,b,c # and a shares memory with b, b shares memory with c, but # c does not share memory with a f = aesara.function( [ aesara.In(x, mutable=True), aesara.In(y, mutable=True), aesara.In(z, mutable=True), aesara.In(m1, mutable=True), aesara.In(m2, mutable=True), aesara.In(m3, mutable=True), ], (aesara.dot((x * 2), m1) + aesara.dot((y * 3), m2) + aesara.dot( (z * 4), m3)), ) # Compute bogus values v = np.asarray([1, 2, 3, 4, 5], dtype="float64") m = np.asarray([[1, 0], [0, 1]], dtype="float64") bogus_vals = f(v[:2], v[1:3], v[2:4], m, m, m) # Since we used inplace operation v and m may be corrupted # so we need to recreate them v = np.asarray([1, 2, 3, 4, 5], dtype="float64") m = np.asarray([[1, 0], [0, 1]], dtype="float64") m_copy1 = m.copy() v_copy1 = v.copy() m_copy2 = m.copy() v_copy2 = v.copy() vals = f(v[:2], v_copy1[1:3], v_copy2[2:4], m, m_copy1, m_copy2) assert np.allclose(vals, bogus_vals)