提交 ef48ace3 authored 作者: James Bergstra's avatar James Bergstra

remove FunctionMaker pickling hack - it makes test_gc hard to write and seems useless

上级 cd2b4a31
......@@ -934,6 +934,7 @@ class FunctionMaker(object):
self.profile = profile = profile or mode_profile
# Handle the case where inputs and/or outputs is a single Variable (not in a list)
self.orig_outputs = outputs
unpack_single = False
return_none = False
if outputs is None:
......@@ -1060,27 +1061,24 @@ class FunctionMaker(object):
fn = self.function_builder(_fn, _i, _o, self.indices, self.outputs, defaults, self.unpack_single, self.return_none, self)
return fn
def _pickle_FunctionMaker(self):
kwargs = dict(
inputs = self.inputs,
outputs = self.orig_outputs,
mode = self.mode,
accept_inplace = self.accept_inplace,
function_builder = self.function_builder,
profile = self.profile,
)
return (_constructor_FunctionMaker, (kwargs,))
def _pickle_FunctionMaker(fm):
if fm.return_none:
outputs = None
else:
if fm.unpack_single:
outputs = fm.outputs[0]
else:
outputs = fm.outputs
#backport
#outputs = None if fm.return_none else (fm.outputs[0] if fm.unpack_single else fm.outputs)
rval = (_constructor_FunctionMaker, (fm.inputs, outputs, fm.mode, fm.accept_inplace))
return rval
def _constructor_FunctionMaker(*args):
return FunctionMaker(*args)
def _constructor_FunctionMaker(kwargs):
return FunctionMaker(**kwargs)
copy_reg.pickle(FunctionMaker, _pickle_FunctionMaker)
def _pickle_slice(s):
return (slice, (s.start, s.stop, s.step))
......
......@@ -20,7 +20,7 @@ def test_no_reuse():
return
assert not 'should not get here'
def test_gc():
def test_gc_never_pickles_temporaries():
x = T.dvector()
#print >> sys.stderr, 'BUILDING GRAPH'
......@@ -32,31 +32,62 @@ def test_gc():
optimizer=None
optimizer='fast_run'
for f_linker, g_linker in [
(theano.PerformLinker(allow_gc = True), theano.PerformLinker(allow_gc=False)),
(theano.OpWiseCLinker(allow_gc = True), theano.OpWiseCLinker(allow_gc=False))]:
#f_linker has garbage collection
#g_linker has no garbage collection
#print >> sys.stderr, 'COMPILING'
f = theano.function([x], r,mode=theano.Mode(optimizer=optimizer, linker=f_linker))
g = theano.function([x], r,mode=theano.Mode(optimizer=optimizer, linker=g_linker))
len_pre_f = len(cPickle.dumps(f))
len_pre_g = len(cPickle.dumps(g))
# should be no difference at first
# In future, FunctionMaker might pickle linker-dependent stuff and make
# this assertion fail.
assert len_pre_f == len_pre_g
def a(fn):
return len(cPickle.dumps(fn.maker))
assert a(f) == a(f) # some sanity checks on the pickling mechanism
assert a(g) == a(g) # some sanity checks on the pickling mechanism
g = theano.function([x], r,mode=theano.Mode(optimizer=optimizer, linker=f_linker))
def b(fn):
return len(
cPickle.dumps(
theano.compile.function_module._pickle_Function(
fn)))
assert b(f) == b(f) # some sanity checks on the pickling mechanism
pre_f = cPickle.dumps(f)
pre_g = cPickle.dumps(g)
def c(fn):
return len(cPickle.dumps(fn))
assert c(f) == c(f) # some sanity checks on the pickling mechanism
assert c(g) == c(g) # some sanity checks on the pickling mechanism
#print >> sys.stderr, 'RUNNING'
# now run the function once to create temporaries within the no-gc
# linker
f(numpy.ones(100, dtype='float64'))
g(numpy.ones(100, dtype='float64'))
# serialize the functions again
post_f = cPickle.dumps(f)
post_g = cPickle.dumps(g)
#because allow_gc should leave the function un-changed by calling
assert len(pre_f) == len(post_f)
#because temporaries that weren't collected shouldn't be pickled anyway
len_post_f = len(post_f)
len_post_g = len(post_g)
#assert that f() didn't cause the function to grow
# allow_gc should leave the function un-changed by calling
assert len_pre_f == len_post_f
#assert that g() didn't cause g to grow
# because temporaries that weren't collected shouldn't be pickled anyway
assert len_post_f == len_post_g, (f_linker, len_post_f, len_post_g)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论