def test_ifelse(self): config1 = config.profile config2 = config.profile_memory try: config.profile = True config.profile_memory = True a, b = scalars("a", "b") x, y = scalars("x", "y") z = ifelse(at.lt(a, b), x * 2, y * 2) p = ProfileStats(False, gpu_checks=False) if config.mode in ("DebugMode", "DEBUG_MODE", "FAST_COMPILE"): m = "FAST_RUN" else: m = None f_ifelse = function([a, b, x, y], z, profile=p, name="test_ifelse", mode=m) val1 = 0.0 val2 = 1.0 big_mat1 = 10 big_mat2 = 11 f_ifelse(val1, val2, big_mat1, big_mat2) finally: config.profile = config1 config.profile_memory = config2
def test_same_names(self): a, x, s = scalars("xxx") # implicit names would cause error. What do we do? f = function([a, x, s], a + x + s) assert f(1, 2, 3) == 6 with pytest.raises(TypeError): f(1, 2, x=3)
def test_shared_state0(self): a = scalar() # the a is for 'anonymous' (un-named). x, s = scalars("xs") f = function( [ x, In(a, value=1.0, name="a"), In(s, value=0.0, update=s + a * x, mutable=True), ], s + a * x, ) g = function( [ x, In(a, value=1.0, name="a"), In(s, value=f.container[s], update=s - a * x, mutable=True), ], s + a * x, ) f(1, 2) assert f[s] == 2 assert g[s] == 2 g(1, 2) assert f[s] == 0 assert g[s] == 0
def test_shared_state2(self): a = scalar() # the a is for 'anonymous' (un-named). x, s = scalars("xs") f = function( [ x, In(a, value=1.0, name="a"), In(s, value=0.0, update=s + a * x, mutable=False), ], s + a * x, ) g = function( [x, In(a, value=1.0, name="a"), In(s, value=f.container[s])], s + a * x ) f(1, 2) assert f[s] == 2 assert g[s] == 2 f(1, 2) assert f[s] == 4 assert g[s] == 4 g(1, 2) # has no effect on state assert f[s] == 4 assert g[s] == 4
def __init__(self): a = scalar() # the a is for 'anonymous' (un-named). x, s = scalars("xs") v = vector("v") self.s = s self.x = x self.v = v self.e = a * x + s self.f1 = function( [ x, In(a, value=1.0, name="a"), In(s, value=0.0, update=s + a * x, mutable=True), ], s + a * x, ) self.f2 = function( [ x, In(a, value=1.0, name="a"), In(s, value=self.f1.container[s], update=s + a * x, mutable=True), ], s + a * x, )
def test_state_access(self): a = scalar() # the a is for 'anonymous' (un-named). x, s = scalars("xs") f = function( [ x, In(a, value=1.0, name="a"), In(s, value=0.0, update=s + a * x) ], s + a * x, ) assert f[a] == 1.0 assert f[s] == 0.0 assert f(3.0) == 3.0 assert f(3.0, a=2.0) == 9.0 # 3.0 + 2*3.0 assert ( f[a] == 1.0 ) # state hasn't changed permanently, we just overrode it last line assert f[s] == 9.0 f[a] = 5.0 assert f[a] == 5.0 assert f(3.0) == 24.0 # 9 + 3*5 assert f[s] == 24.0
def test_copy(self): a = scalar() # the a is for 'anonymous' (un-named). x, s = scalars("xs") f = function( [ x, In(a, value=1.0, name="a"), In(s, value=0.0, update=s + a * x, mutable=True), ], s + a * x, ) g = copy.copy(f) # if they both return, assume that they return equivalent things. assert g.container[x].storage is not f.container[x].storage assert g.container[a].storage is not f.container[a].storage assert g.container[s].storage is not f.container[s].storage assert g.value[a] is f.value[a] # should not have been copied assert ( g.value[s] is not f.value[s] ) # should have been copied because it is mutable. assert not (g.value[s] != f.value[s]).any() # its contents should be identical assert f(2, 1) == g( 2 ) # they should be in sync, default value should be copied. assert f(2, 1) == g( 2 ) # they should be in sync, default value should be copied. f(1, 2) # put them out of sync assert f(1, 2) != g(1, 2) # they should not be equal anymore.
def __init__(self): x, y, z = scalars("xyz") e = at.sigmoid((x + y + z)**2) op = OpFromGraph([x, y, z], [e]) e2 = op(x, y, z) self.inputs = [x, y, z] self.outputs = [e2]
def __init__(self): x, y, z = scalars("xyz") e = aesara.tensor.sigmoid((x + y + z) ** 2) op = aesara.compile.builders.OpFromGraph([x, y, z], [e]) e2 = op(x, y, z) self.inputs = [x, y, z] self.outputs = [e2]
def test_callback_with_ifelse(self): a, b, c = scalars("abc") f = function( [a, b, c], ifelse(a, 2 * b, 2 * c), mode=Mode(optimizer=None, linker=VMLinker(callback=self.callback)), ) f(1, 2, 3) assert self.n_callbacks["IfElse"] == 2
def __init__(self): x, y, z = scalars("xyz") e = x * y op = OpFromGraph([x, y], [e]) e2 = op(x, y) + z op2 = OpFromGraph([x, y, z], [e2]) e3 = op2(x, y, z) + z self.inputs = [x, y, z] self.outputs = [e3]
def __init__(self): x, y, z = scalars("xyz") e = x * y op = aesara.compile.builders.OpFromGraph([x, y], [e]) e2 = op(x, y) + z op2 = aesara.compile.builders.OpFromGraph([x, y, z], [e2]) e3 = op2(x, y, z) + z self.inputs = [x, y, z] self.outputs = [e3]
def test_deepcopy(self): a = scalar() # the a is for 'anonymous' (un-named). x, s = scalars("xs") f = function( [ x, In(a, value=1.0, name="a"), In(s, value=0.0, update=s + a * x, mutable=True), ], s + a * x, ) try: g = copy.deepcopy(f) except NotImplementedError as e: if e[0].startswith("DebugMode is not picklable"): return else: raise # if they both return, assume that they return equivalent things. # print [(k,id(k)) for k in f.finder.keys()] # print [(k,id(k)) for k in g.finder.keys()] assert g.container[0].storage is not f.container[0].storage assert g.container[1].storage is not f.container[1].storage assert g.container[2].storage is not f.container[2].storage assert x not in g.container assert x not in g.value assert len(f.defaults) == len(g.defaults) assert f._check_for_aliased_inputs is g._check_for_aliased_inputs assert f.name == g.name assert f.maker.fgraph.name == g.maker.fgraph.name # print 'f.defaults = %s' % (f.defaults, ) # print 'g.defaults = %s' % (g.defaults, ) for ((f_req, f_feed, f_val), (g_req, g_feed, g_val)) in zip( f.defaults, g.defaults ): assert f_req == g_req and f_feed == g_feed and f_val == g_val assert g.value[1] is not f.value[1] # should not have been copied assert ( g.value[2] is not f.value[2] ) # should have been copied because it is mutable. assert not (g.value[2] != f.value[2]).any() # its contents should be identical assert f(2, 1) == g( 2 ) # they should be in sync, default value should be copied. assert f(2, 1) == g( 2 ) # they should be in sync, default value should be copied. f(1, 2) # put them out of sync assert f(1, 2) != g(1, 2) # they should not be equal anymore. g(1, 2) # put them back in sync assert f(3) == g(3) # They should be in sync again.
def test_callback(self): a, b, c = scalars("abc") f = function( [a, b, c], (a + b) + c, mode=Mode(optimizer=None, linker=VMLinker(callback=self.callback)), ) f(1, 2, 3) assert sum(self.n_callbacks.values()) == len(f.maker.fgraph.toposort()) f(1, 2, 3) assert sum( self.n_callbacks.values()) == len(f.maker.fgraph.toposort()) * 2
def test_naming_rule1(self): a = scalar() # the a is for 'anonymous' (un-named). x, s = scalars("xs") f = function([a, s], a / s) assert f(1, 2) == 0.5 assert f(2, 1) == 2.0 assert f(2, s=1) == 2.0 checkfor( self, lambda: f(q=2, s=1), TypeError ) # got unexpected keyword argument 'q' checkfor( self, lambda: f(a=2, s=1), TypeError ) # got unexpected keyword argument 'a'
def test_naming_rule1(self): a = scalar() # the a is for 'anonymous' (un-named). x, s = scalars("xs") f = function([a, s], a / s) assert f(1, 2) == 0.5 assert f(2, 1) == 2.0 assert f(2, s=1) == 2.0 with pytest.raises(TypeError): # got unexpected keyword argument 'q' f(q=2, s=1) with pytest.raises(TypeError): # got unexpected keyword argument 'a' f(a=2, s=1)
def test_naming_rule2(self): a = scalar() # the a is for 'anonymous' (un-named). x, s = scalars("xs") # x's name is ignored because it is followed by anonymous parameter a. # Ignore unused input x, as it hides the other error f = function([x, a, s], a / s, on_unused_input="ignore") assert f(9, 1, 2) == 0.5 assert f(9, 2, 1) == 2.0 assert f(9, 2, s=1) == 2.0 checkfor( self, lambda: f(x=9, a=2, s=1), TypeError ) # got unexpected keyword argument 'x' checkfor( self, lambda: f(5.0, x=9), TypeError ) # got unexpected keyword argument 'x'
def test_pickle(self): a = scalar() # the a is for 'anonymous' (un-named). x, s = scalars("xs") f = function( [ x, In(a, value=1.0, name="a"), In(s, value=0.0, update=s + a * x, mutable=True), ], s + a * x, ) try: # Note that here we also test protocol 0 on purpose, since it # should work (even though one should not use it). g = pickle.loads(pickle.dumps(f, protocol=0)) g = pickle.loads(pickle.dumps(f, protocol=-1)) except NotImplementedError as e: if e[0].startswith("DebugMode is not picklable"): return else: raise # if they both return, assume that they return equivalent things. # print [(k,id(k)) for k in f.finder.keys()] # print [(k,id(k)) for k in g.finder.keys()] assert g.container[0].storage is not f.container[0].storage assert g.container[1].storage is not f.container[1].storage assert g.container[2].storage is not f.container[2].storage assert x not in g.container assert x not in g.value assert g.value[1] is not f.value[1] # should not have been copied assert ( g.value[2] is not f.value[2] ) # should have been copied because it is mutable. assert not (g.value[2] != f.value[2]).any() # its contents should be identical assert f(2, 1) == g( 2 ) # they should be in sync, default value should be copied. assert f(2, 1) == g( 2 ) # they should be in sync, default value should be copied. f(1, 2) # put them out of sync assert f(1, 2) != g(1, 2) # they should not be equal anymore.
def test_weird_names(self): a, x, s = scalars("xxx") checkfor(self, lambda: function([In(a, name=[])], []), TypeError) def t(): f = function( [ In(a, name={"adsf", ()}, value=1.0), In(x, name=(), value=2.0), In(s, name=scalar(), value=3.0), ], a + x + s, ) return f checkfor(self, t, TypeError)
def test_naming_rule0(self): x, s = scalars("xs") f = function([x, s], x / s) assert f(1, 2) == 0.5 assert f(2, 1) == 2.0 assert f(s=2, x=1) == 0.5 assert f(x=2, s=1) == 2.0 assert f(2, s=1) == 2.0 checkfor( self, lambda: f(2, x=2.0), TypeError ) # got multiple values for keyword argument 'x' checkfor( self, lambda: f(x=1), TypeError ) # takes exactly 2 non-keyword arguments (1 given) checkfor( self, lambda: f(s=1), TypeError ) # takes exactly 2 non-keyword arguments (0 given)
def test_naming_rule0(self): x, s = scalars("xs") f = function([x, s], x / s) assert f(1, 2) == 0.5 assert f(2, 1) == 2.0 assert f(s=2, x=1) == 0.5 assert f(x=2, s=1) == 2.0 assert f(2, s=1) == 2.0 with pytest.raises(TypeError): # got multiple values for keyword argument 'x' f(2, x=2.0) with pytest.raises(TypeError): # takes exactly 2 non-keyword arguments (1 given) f(x=1) with pytest.raises(TypeError): # takes exactly 2 non-keyword arguments (0 given) f(s=1)
def test_naming_rule4(self): a = scalar() # the a is for 'anonymous' (un-named). x, s = scalars("xs") f = function([x, In(a, value=1.0, name="a"), s], a / s + x) assert f(9, 2, 4) == 9.5 # can specify all args in order assert f(9, 2, s=4) == 9.5 # can give s as kwarg assert f(9, s=4) == 9.25 # can give s as kwarg, get default a assert f(9, a=2, s=4) == 9.5 # can give s as kwarg, a as kwarg assert f(x=9, a=2, s=4) == 9.5 # can give all kwargs assert f(x=9, s=4) == 9.25 # can give all kwargs with pytest.raises(TypeError): # takes exactly 3 non-keyword arguments (0 given) f() with pytest.raises(TypeError): # got multiple values for keyword argument 'x' f(5.0, x=9)
def test_shared_state_not_implicit(self): # This test is taken from the documentation in # doc/topics/function.txt. If it does not pass anymore and yet the # behavior is still intended the doc and the test should both be # updated accordingly. x, s = scalars("xs") inc = function([x, In(s, update=(s + x), value=10.0)], []) dec = function( [x, In(s, update=(s - x), value=inc.container[s], implicit=False)], [] ) assert dec[s] is inc[s] inc[s] = 2 assert dec[s] == 2 dec(1) assert inc[s] == 1 dec(1, 0) assert inc[s] == -1 assert dec[s] == -1
def test_naming_rule3(self): a = scalar() # the a is for 'anonymous' (un-named). x, s = scalars("xs") # x's name is not ignored (as in test_naming_rule2) because a has a default value. f = function([x, In(a, value=1.0), s], a / s + x) assert f(9, 2, 4) == 9.5 # can specify all args in order assert f(9, 2, s=4) == 9.5 # can give s as kwarg assert f(9, s=4) == 9.25 # can give s as kwarg, get default a assert f(x=9, s=4) == 9.25 # can give s as kwarg, omit a, x as kw with pytest.raises(TypeError): # got unexpected keyword argument 'a' f(x=9, a=2, s=4) with pytest.raises(TypeError): # takes exactly 3 non-keyword arguments (0 given) f() with pytest.raises(TypeError): # takes exactly 3 non-keyword arguments (1 given) f(x=9)
def test_weird_names(self): a, x, s = scalars("xxx") with pytest.raises(TypeError): function([In(a, name=[])], []) def t(): f = function( [ In(a, name={"adsf", ()}, value=1.0), In(x, name=(), value=2.0), In(s, name=scalar(), value=3.0), ], a + x + s, ) return f with pytest.raises(TypeError): t()
def test_copy(self): a = scalar() x, s = scalars("xs") f = function( [ x, In(a, value=1.0, name="a"), In(s, value=0.0, update=s + a * x, mutable=True), ], s + a * x, ) g = copy.copy(f) assert f.unpack_single == g.unpack_single assert f.trust_input == g.trust_input assert g.container[x].storage is not f.container[x].storage assert g.container[a].storage is not f.container[a].storage assert g.container[s].storage is not f.container[s].storage # Should not have been copied assert g.value[a] is f.value[a] # Should have been copied because it is mutable assert g.value[s] is not f.value[s] # Their contents should be equal, though assert np.array_equal(g.value[s], f.value[s]) # They should be in sync, default value should be copied assert np.array_equal(f(2, 1), g(2)) # They should be in sync, default value should be copied assert np.array_equal(f(2, 1), g(2)) # Put them out of sync f(1, 2) # They should not be equal anymore assert not np.array_equal(f(1, 2), g(1, 2))
def test_use_c_thunks(): a_at = scalars("a") b_at = vectors("b") a = np.array(0.0).astype(config.floatX) b = np.array([2.0]).astype(config.floatX) cases = [False] if config.cxx: cases.append(True) for use_c_thunks in cases: f = function( [a_at, b_at], a_at * b_at, mode=Mode(optimizer=None, linker=VMLinker(c_thunks=use_c_thunks, use_cloop=False)), ) assert np.array_equal(a * b, f(a, b)) assert any([hasattr(t, "cthunk") for t in f.fn.thunks]) == use_c_thunks
def test_deepcopy_shared_container(self): # Ensure that shared containers remain shared after a deep copy. a, x = scalars("ax") h = function([In(a, value=0.0)], a) f = function([x, In(a, value=h.container[a], implicit=True)], x + a) try: memo = {} ac = copy.deepcopy(a) memo.update({id(a): ac}) hc = copy.deepcopy(h, memo=memo) memo.update({id(h): hc}) fc = copy.deepcopy(f, memo=memo) except NotImplementedError as e: if e[0].startswith("DebugMode is not picklable"): return else: raise h[a] = 1 hc[ac] = 2 assert f[a] == 1 assert fc[ac] == 2
def test_multiple_functions(self): a = scalar() # the a is for 'anonymous' (un-named). x, s = scalars("xs") v = vector("v") # put in some inputs list_of_things = [s, x, v] # some derived thing, whose inputs aren't all in the list list_of_things.append(a * x + s) f1 = function( [ x, In(a, value=1.0, name="a"), In(s, value=0.0, update=s + a * x, mutable=True), ], s + a * x, ) list_of_things.append(f1) # now put in a function sharing container with the previous one f2 = function( [ x, In(a, value=1.0, name="a"), In(s, value=f1.container[s], update=s + a * x, mutable=True), ], s + a * x, ) list_of_things.append(f2) assert isinstance(f2.container[s].storage, list) assert f2.container[s].storage is f1.container[s].storage # now put in a function with non-scalar v_value = np.asarray([2, 3, 4.0], dtype=config.floatX) f3 = function([x, In(v, value=v_value)], x + v) list_of_things.append(f3) # try to pickle the entire things try: saved_format = pickle.dumps(list_of_things, protocol=-1) new_list_of_things = pickle.loads(saved_format) except NotImplementedError as e: if e[0].startswith("DebugMode is not picklable"): return else: raise # now test our recovered new_list_of_things # it should be totally unrelated to the original # it should be interdependent in the same way as the original ol = list_of_things nl = new_list_of_things for i in range(4): assert nl[i] != ol[i] assert nl[i].type == ol[i].type assert nl[i].type is not ol[i].type # see if the implicit input got stored assert ol[3].owner.inputs[1] is s assert nl[3].owner.inputs[1] is not s assert nl[3].owner.inputs[1].type == s.type # moving on to the functions... for i in range(4, 7): assert nl[i] != ol[i] # looking at function number 1, input 's' assert nl[4][nl[0]] is not ol[4][ol[0]] assert nl[4][nl[0]] == ol[4][ol[0]] assert nl[4](3) == ol[4](3) # looking at function number 2, input 's' # make sure it's shared with the first function assert ol[4].container[ol[0]].storage is ol[5].container[ol[0]].storage assert nl[4].container[nl[0]].storage is nl[5].container[nl[0]].storage assert nl[5](3) == ol[5](3) assert nl[4].value[nl[0]] == 6 assert np.all(nl[6][nl[2]] == np.asarray([2, 3.0, 4]))
def setup_method(self): self.x, self.y = scalars("x", "y") self.z = self.x + self.y self.w = 2 * self.z