def test_deepcopy_trust_input(self): a = tt.dscalar() # the a is for 'anonymous' (un-named). x, s = tt.dscalars("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, ) f.trust_input = True try: g = copy.deepcopy(f) except NotImplementedError as e: if e[0].startswith("DebugMode is not picklable"): return else: raise assert f.trust_input is g.trust_input f(np.asarray(2.0)) with pytest.raises( (ValueError, AttributeError, theano.compile.debugmode.InvalidValueError) ): f(2.0) g(np.asarray(2.0)) with pytest.raises( (ValueError, AttributeError, theano.compile.debugmode.InvalidValueError) ): g(2.0)
def test_multiple_functions(self): a = T.scalar() # the a is for 'anonymous' (un-named). x, s = T.scalars('xs') v = T.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 = numpy.asarray([2, 3, 4.], 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 = cPickle.dumps(list_of_things, protocol=-1) new_list_of_things = cPickle.loads(saved_format) except NotImplementedError, e: if e[0].startswith('DebugMode is not picklable'): return else: raise
def test_param_allow_downcast_int(self): a = tensor.wvector("a") # int16 b = tensor.bvector("b") # int8 c = tensor.bscalar("c") # int8 f = pfunc( [ In(a, allow_downcast=True), In(b, allow_downcast=False), In(c, allow_downcast=None), ], (a + b + c), ) # Both values are in range. Since they're not ndarrays (but lists), # they will be converted, and their value checked. assert np.all(f([3], [6], 1) == 10) # Values are in range, but a dtype too large has explicitly been given # For performance reasons, no check of the data is explicitly performed # (It might be OK to change this in the future.) with pytest.raises(TypeError): f([3], np.array([6], dtype="int16"), 1) # Value too big for a, silently ignored assert np.all(f([2**20], np.ones(1, dtype="int8"), 1) == 2) # Value too big for b, raises TypeError with pytest.raises(TypeError): f([3], [312], 1) # Value too big for c, raises TypeError with pytest.raises(TypeError): f([3], [6], 806)
def test_shared_state2(self): a = tt.scalar() # the a is for 'anonymous' (un-named). x, s = tt.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 test_param_allow_downcast_floatX(self): a = tensor.fscalar("a") b = tensor.fscalar("b") c = tensor.fscalar("c") f = pfunc( [ In(a, allow_downcast=True), In(b, allow_downcast=False), In(c, allow_downcast=None), ], (a + b + c), ) # If the values can be accurately represented, everything is OK assert np.all(f(0, 0, 0) == 0) # If allow_downcast is True, idem assert np.allclose(f(0.1, 0, 0), 0.1) # If allow_downcast is False, nope with pytest.raises(TypeError): f(0, 0.1, 0) # If allow_downcast is None, it should work iff floatX=float32 if config.floatX == "float32": assert np.allclose(f(0, 0, 0.1), 0.1) else: with pytest.raises(TypeError): f(0, 0, 0.1)
def test_copy(self): a = tt.scalar() # the a is for 'anonymous' (un-named). x, s = tt.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 test_shared_state0(self): a = tt.scalar() # the a is for 'anonymous' (un-named). x, s = tt.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 __init__(self): a = tt.scalar() # the a is for 'anonymous' (un-named). x, s = tt.scalars("xs") v = tt.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_param_allow_downcast_vector_floatX(self): a = tensor.fvector("a") b = tensor.fvector("b") c = tensor.fvector("c") f = pfunc( [ In(a, allow_downcast=True), In(b, allow_downcast=False), In(c, allow_downcast=None), ], (a + b + c), ) # If the values can be accurately represented, everything is OK z = [0] assert np.all(f(z, z, z) == 0) # If allow_downcast is True, idem assert np.allclose(f([0.1], z, z), 0.1) # If allow_downcast is False, nope with pytest.raises(TypeError): f(z, [0.1], z) # If allow_downcast is None, like False with pytest.raises(TypeError): f(z, z, [0.1])
def test_pickle(self): a = T.scalar() # the a is for 'anonymous' (un-named). x, s = T.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()] self.assertFalse(g.container[0].storage is f.container[0].storage) self.assertFalse(g.container[1].storage is f.container[1].storage) self.assertFalse(g.container[2].storage is f.container[2].storage) self.assertFalse(x in g.container) self.assertFalse(x in g.value) self.assertFalse(g.value[1] is f.value[1]) # should not have been copied self.assertFalse(g.value[2] is f.value[2]) # should have been copied because it is mutable. self.assertFalse((g.value[2] != f.value[2]).any()) # its contents should be identical self.assertTrue(f(2, 1) == g(2)) # they should be in sync, default value should be copied. self.assertTrue(f(2, 1) == g(2)) # they should be in sync, default value should be copied. f(1, 2) # put them out of sync self.assertFalse(f(1, 2) == g(1, 2)) # they should not be equal anymore.
def test_state_access(self): a = tt.scalar() # the a is for 'anonymous' (un-named). x, s = tt.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_state_access(self): a = T.scalar() # the a is for 'anonymous' (un-named). x, s = T.scalars('xs') f = function([ x, In(a, value=1.0, name='a'), In(s, value=0.0, update=s + a * x) ], s + a * x) self.assertTrue(f[a] == 1.0) self.assertTrue(f[s] == 0.0) self.assertTrue(f(3.0) == 3.0) self.assertTrue(f(3.0, a=2.0) == 9.0) # 3.0 + 2*3.0 self.assertTrue( f[a] == 1.0 ) # state hasn't changed permanently, we just overrode it last line self.assertTrue(f[s] == 9.0) f[a] = 5.0 self.assertTrue(f[a] == 5.0) self.assertTrue(f(3.0) == 24.0) # 9 + 3*5 self.assertTrue(f[s] == 24.0)
def t(): f = function([ In(a, name=set(['adsf', ()]), value=1.0), In(x, name=(), value=2.0), In(s, name=T.scalar(), value=3.0) ], a + x + s) return f
def test_copy(self): a = T.scalar() # the a is for 'anonymous' (un-named). x, s = T.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. self.assertFalse(g.container[x].storage is f.container[x].storage) self.assertFalse(g.container[a].storage is f.container[a].storage) self.assertFalse(g.container[s].storage is f.container[s].storage) self.assertFalse(g.value[a] is not f.value[a]) # should not have been copied self.assertFalse( g.value[s] is f.value[s]) # should have been copied because it is mutable. self.assertFalse( (g.value[s] != f.value[s]).any()) # its contents should be identical self.assertTrue(f(2, 1) == g( 2)) # they should be in sync, default value should be copied. self.assertTrue(f(2, 1) == g( 2)) # they should be in sync, default value should be copied. f(1, 2) # put them out of sync self.assertFalse(f(1, 2) == g(1, 2)) # they should not be equal anymore.
def test_in_allow_downcast_floatX(self): a = theano.tensor.fscalar('a') b = theano.tensor.fscalar('b') c = theano.tensor.fscalar('c') f = theano.function([ In(a, allow_downcast=True), In(b, allow_downcast=False), In(c, allow_downcast=None) ], (a + b + c)) # If the values can be accurately represented, everything is OK assert numpy.all(f(0, 0, 0) == 0) # If allow_downcast is True, idem assert numpy.allclose(f(0.1, 0, 0), 0.1) # If allow_downcast is False, nope self.assertRaises(TypeError, f, 0, 0.1, 0) # If allow_downcast is None, it should work iff floatX=float32 if theano.config.floatX == 'float32': assert numpy.allclose(f(0, 0, 0.1), 0.1) else: self.assertRaises(TypeError, f, 0, 0, 0.1)
def test_in_allow_downcast_int(self): a = theano.tensor.wvector('a') # int16 b = theano.tensor.bvector('b') # int8 c = theano.tensor.bscalar('c') # int8 f = theano.function([ In(a, allow_downcast=True), In(b, allow_downcast=False), In(c, allow_downcast=None) ], (a + b + c)) # Both values are in range. Since they're not ndarrays (but lists), # they will be converted, and their value checked. assert numpy.all(f([3], [6], 1) == 10) # Values are in range, but a dtype too large has explicitly been given # For performance reasons, no check of the data is explicitly performed # (It might be OK to change this in the future.) self.assertRaises(TypeError, f, [3], numpy.array([6], dtype='int16'), 1) # Value too big for a, silently ignored assert numpy.all(f([2**20], numpy.ones(1, dtype='int8'), 1) == 2) # Value too big for b, raises TypeError self.assertRaises(TypeError, f, [3], [312], 1) # Value too big for c, raises TypeError self.assertRaises(TypeError, f, [3], [6], 806)
def test_deepcopy(self): a = T.scalar() # the a is for 'anonymous' (un-named). x, s = T.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()] self.assertFalse(g.container[0].storage is f.container[0].storage) self.assertFalse(g.container[1].storage is f.container[1].storage) self.assertFalse(g.container[2].storage is f.container[2].storage) self.assertFalse(x in g.container) self.assertFalse(x in g.value) self.assertTrue(len(f.defaults) == len(g.defaults)) self.assertTrue( f._check_for_aliased_inputs is g._check_for_aliased_inputs) self.assertTrue(f.name == g.name) self.assertTrue(f.maker.fgraph.name == g.maker.fgraph.name) # print 'f.defaults = %s' % (f.defaults, ) # print 'g.defaults = %s' % (g.defaults, ) self.assertTrue( all([ f_req == g_req and f_feed == g_feed and f_val == g_val for ((f_req, f_feed, f_val), (g_req, g_feed, g_val)) in zip(f.defaults, g.defaults) ])) self.assertFalse( g.value[1] is f.value[1]) # should not have been copied self.assertFalse( g.value[2] is f.value[2]) # should have been copied because it is mutable. self.assertFalse( (g.value[2] != f.value[2]).any()) # its contents should be identical self.assertTrue(f(2, 1) == g( 2)) # they should be in sync, default value should be copied. self.assertTrue(f(2, 1) == g( 2)) # they should be in sync, default value should be copied. f(1, 2) # put them out of sync self.assertFalse(f(1, 2) == g(1, 2)) # they should not be equal anymore. g(1, 2) # put them back in sync self.assertTrue(f(3) == g(3)) # They should be in sync again.
def t(): f = function( [ In(a, name={"adsf", ()}, value=1.0), In(x, name=(), value=2.0), In(s, name=tt.scalar(), value=3.0), ], a + x + s, ) return f
def test_deepcopy(self): a = tt.scalar() # the a is for 'anonymous' (un-named). x, s = tt.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_deepcopy(self): a = T.scalar() # the a is for 'anonymous' (un-named). x,s = T.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, e: if e[0].startswith('DebugMode is not picklable'): return else: raise
def test_shared_state0(self): a = T.scalar() # the a is for 'anonymous' (un-named). x,s = T.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) self.assertTrue(f[s] == 2) self.assertTrue(g[s] == 2) g(1, 2) self.assertTrue(f[s] == 0) self.assertTrue(g[s] == 0)
def __init__(self): a = T.scalar() # the a is for 'anonymous' (un-named). x,s = T.scalars('xs') v = T.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_random_function_ndim(self): # Test that random_function helper function accepts argument ndim rng_R = random_state_type() # ndim is an optional argument indicating the length of the 'shape' # ndim not specified, OK post_out4, out4 = uniform(rng_R, (4, )) # ndim specified, consistent with shape, OK post_out1_4, out1_4 = uniform(rng_R, (4, ), ndim=1) post_out2_4_4, out2_4_4 = uniform(rng_R, (4, 4), ndim=2) # ndim specified, but not compatible with shape with pytest.raises(ValueError): uniform(rng_R, (4, ), ndim=2) f_ok = function( [ In( rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_out2_4_4, mutable=True, ) ], [out4, out1_4, out2_4_4], accept_inplace=True, ) # The correct cases should execute properly o4, o1_4, o2_4_4 = f_ok() # Check the sanity of the answers assert np.allclose(o4, o1_4) assert np.allclose(o4, o2_4_4[0])
def test_normal(self): # Test that raw_random.normal generates the same results as numpy. # Check over two calls to see if the random state is correctly updated. rng_R = random_state_type() # Use non-default parameters post_r, out = normal(rng_R, (2, 3), 4.0, 2.0) f = function( [ In( rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True, ) ], [out], accept_inplace=True, ) numpy_rng = np.random.RandomState(utt.fetch_seed()) val0 = f() val1 = f() numpy_val0 = numpy_rng.normal(4.0, 2.0, size=(2, 3)) numpy_val1 = numpy_rng.normal(4.0, 2.0, size=(2, 3)) assert np.allclose(val0, numpy_val0) assert np.allclose(val1, numpy_val1)
def test_poisson(self): # Test that raw_random.poisson generates the same results as numpy. # Check over two calls to see if the random state is correctly updated. rng_R = random_state_type() # Use non-default parameters, and larger dimensions because of # the integer nature of the result post_r, out = poisson(rng_R, lam=5, size=(11, 8)) f = function( [ In( rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True, ) ], [out], accept_inplace=True, ) numpy_rng = np.random.RandomState(utt.fetch_seed()) val0 = f() val1 = f() numpy_val0 = numpy_rng.poisson(5, size=(11, 8)) numpy_val1 = numpy_rng.poisson(5, size=(11, 8)) assert np.allclose(val0, numpy_val0) assert np.allclose(val1, numpy_val1)
def test_multinomial(self): # Test that raw_random.multinomial generates the same results as numpy. # Check over two calls to see if the random state is correctly updated. rng_R = random_state_type() post_r, out = multinomial(rng_R, (7, 3), 6, [0.2] * 5) f = function( [ In( rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True, ) ], [out], accept_inplace=True, ) numpy_rng = np.random.RandomState(utt.fetch_seed()) (val0, ) = f() (val1, ) = f() numpy_val0 = numpy_rng.multinomial(6, [0.2] * 5, (7, 3)) numpy_val1 = numpy_rng.multinomial(6, [0.2] * 5, (7, 3)) assert np.all(val0 == numpy_val0) assert np.all(val1 == numpy_val1) assert val0.shape == (7, 3, 5) assert val1.shape == (7, 3, 5)
def test_doc(self): # Ensure the code given in pfunc.txt works as expected # Example #1. a = lscalar() b = shared(1) f1 = pfunc([a], (a + b)) f2 = pfunc([In(a, value=44)], a + b, updates={b: b + 1}) assert b.get_value() == 1 assert f1(3) == 4 assert f2(3) == 4 assert b.get_value() == 2 assert f1(3) == 5 b.set_value(0) assert f1(3) == 3 # Example #2. a = tensor.lscalar() b = shared(7) f1 = pfunc([a], a + b) f2 = pfunc([a], a * b) assert f1(5) == 12 b.set_value(8) assert f1(5) == 13 assert f2(4) == 32
def test_no_inplace(self): # Test that when not running inplace, the RandomState is not updated rf = RandomFunction("uniform", tensor.dvector) rng_R = random_state_type() post_r, out = rf(rng_R, (3, ), 0.0, 1.0) f = function([rng_R], [post_r, out]) rng = np.random.RandomState(utt.fetch_seed()) rng0, val0 = f(rng) rng_ = np.random.RandomState(utt.fetch_seed()) # rng should still be in a fresh state assert rng_R.type.values_eq(rng, rng_) # rng0 should be in an updated state assert not rng_R.type.values_eq(rng, rng0) f2 = function([In(rng_R, value=rng, update=post_r, mutable=False)], [post_r, out]) rng2, val2 = f2() # rng should be in a fresh state assert rng_R.type.values_eq(rng, rng_) # rng2 should be in an updated state assert not rng_R.type.values_eq(rng, rng2) # The updated state should be the same for both functions assert rng_R.type.values_eq(rng2, rng0) rng3, val3 = f2() # rng2 should not have changed assert rng_R.type.values_eq(rng2, rng0) # rng3 should be an updated again version of rng2 assert not rng_R.type.values_eq(rng3, rng2) assert not rng_R.type.values_eq(rng3, rng)
def test_pickle(self): a = T.scalar() # the a is for 'anonymous' (un-named). x,s = T.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 = cPickle.loads(cPickle.dumps(f, protocol=0)) g = cPickle.loads(cPickle.dumps(f, protocol=-1)) except NotImplementedError, e: if e[0].startswith('DebugMode is not picklable'): return else: raise
def test_binomial(self): # Test that raw_random.binomial generates the same results as numpy. # Check over two calls to see if the random state is correctly updated. rng_R = random_state_type() # Use non-default parameters, and larger dimensions because of # the integer nature of the result post_r, bin = binomial(rng_R, (7, 12), 5, 0.8) f = function( [ In( rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True, ) ], [bin], accept_inplace=True, ) numpy_rng = np.random.RandomState(utt.fetch_seed()) val0 = f() val1 = f() numpy_val0 = numpy_rng.binomial(5, 0.8, size=(7, 12)) numpy_val1 = numpy_rng.binomial(5, 0.8, size=(7, 12)) assert np.all(val0 == numpy_val0) assert np.all(val1 == numpy_val1)