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

merge

...@@ -537,11 +537,11 @@ class Test_ViewMap(unittest.TestCase): ...@@ -537,11 +537,11 @@ class Test_ViewMap(unittest.TestCase):
class Test_check_isfinite(unittest.TestCase): class Test_check_isfinite(unittest.TestCase):
def setUp(self): def setUp(self):
print 'Up' self.old_ts = theano.tensor.TensorType.filter_checks_isfinite
self.old_val = theano.tensor.TensorType.filter_checks_isfinite self.old_dm = theano.compile.mode.predefined_modes['DEBUG_MODE'].check_isfinite
def tearDown(self): def tearDown(self):
print 'Down' theano.tensor.TensorType.filter_checks_isfinite = self.old_ts
theano.tensor.TensorType.filter_checks_isfinite = self.old_val theano.compile.mode.predefined_modes['DEBUG_MODE'].check_isfinite = self.old_dm
def test_check_isfinite(self): def test_check_isfinite(self):
x = theano.tensor.vector() x = theano.tensor.vector()
...@@ -551,16 +551,19 @@ class Test_check_isfinite(unittest.TestCase): ...@@ -551,16 +551,19 @@ class Test_check_isfinite(unittest.TestCase):
# this should work # this should work
f(numpy.log([3, 4, 5])) f(numpy.log([3, 4, 5]))
# if TensorType.filter_checks_isfinite were true, these would raise ValueError
# if not, DebugMode will check internally, and raise InvalidValueError
# passing an invalid value as an input should trigger ValueError # passing an invalid value as an input should trigger ValueError
self.failUnlessRaises(ValueError, f, numpy.log([3, -4, 5])) self.failUnlessRaises(debugmode.InvalidValueError, f, numpy.log([3, -4, 5]))
self.failUnlessRaises(ValueError, f, numpy.asarray([0, 1.0, 0])/0) self.failUnlessRaises(debugmode.InvalidValueError, f, numpy.asarray([0, 1.0, 0])/0)
self.failUnlessRaises(ValueError, f, numpy.asarray([1.0, 1.0, 1.0])/0) self.failUnlessRaises(debugmode.InvalidValueError, f, numpy.asarray([1.0, 1.0, 1.0])/0)
# generating an invalid value internally should trigger InvalidValueError # generating an invalid value internally should trigger InvalidValueError
self.failUnlessRaises(debugmode.InvalidValueError, g, [3,-4,5]) self.failUnlessRaises(debugmode.InvalidValueError, g, [3,-4,5])
# this should disable the exception # this should disable the exception
theano.tensor.TensorType.filter_checks_isfinite = False theano.tensor.TensorType.filter_checks_isfinite = False
theano.compile.mode.predefined_modes['DEBUG_MODE'].check_isfinite = False
# insert several Inf # insert several Inf
f(numpy.asarray([1.0, 1.0, 1.0])/0) f(numpy.asarray([1.0, 1.0, 1.0])/0)
......
...@@ -85,51 +85,83 @@ def fetch_val_for_key(key): ...@@ -85,51 +85,83 @@ def fetch_val_for_key(key):
except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
raise KeyError(key) raise KeyError(key)
_config_var_list = []
def _config_print(thing, buf):
for cv in _config_var_list:
print >> buf, cv
print >> buf, " Doc: ", cv.doc
print >> buf, " Value: ", cv.val
print >> buf, ""
class TheanoConfigParser(object): class TheanoConfigParser(object):
#properties are installed by AddConfigVar #properties are installed by AddConfigVar
_i_am_a_config_class = True
def __str__(self): def __str__(self):
sio = StringIO.StringIO() sio = StringIO.StringIO()
_config_print(self.__class__, sio) _config_print(self.__class__, sio)
return sio.getvalue() return sio.getvalue()
pass
# N.B. all instances of TheanoConfigParser give access to the same properties. # N.B. all instances of TheanoConfigParser give access to the same properties.
config = TheanoConfigParser() config = TheanoConfigParser()
_config_var_list = [] #
# The data structure at work here is a tree of CLASSES with CLASS ATTRIBUTES/PROPERTIES that
def _config_print(thing, buf): # are either a) INSTANTIATED dynamically-generated CLASSES, or b) ConfigParam instances.
for cv in _config_var_list: # The root of this tree is the TheanoConfigParser CLASS, and the internal nodes are the SubObj
print >> buf, cv # classes created inside of AddConfigVar().
print >> buf, " Doc: ", cv.doc # Why this design ?
print >> buf, " Value: ", cv.val # - The config object is a true singleton. Every instance of TheanoConfigParser is an empty
print >> buf, "" # instance that looks up attributes/properties in the [single] TheanoConfigParser.__dict__
# - The subtrees provide the same interface as the root
# - ConfigParser subclasses control get/set of config properties to guard against craziness.
def AddConfigVar(name, doc, configparam, root=config):
"""Add a new variable to theano.config
:type name: string for form "[section0.[section1.[etc]]].option"
:param name: the full name for this configuration variable.
:type doc: string
:param doc: What does this variable specify?
:type configparam: ConfigParam instance
:param configparam: an object for getting and setting this configuration parameter
:type root: object
:param root: used for recusive calls -- don't provide an argument for this parameter.
:returns: None
"""
# this method also performs some of the work of initializing ConfigParam instances
def AddConfigVar(name, doc, thing, cls=TheanoConfigParser): if root is config:
if cls == TheanoConfigParser: #only set the name in the first call, not the recursive ones
thing.fullname = name configparam.fullname = name
if hasattr(TheanoConfigParser, name): sections = name.split('.')
raise ValueError('This name is already taken') if len(sections) > 1:
parts = name.split('.')
if len(parts) > 1:
# set up a subobject # set up a subobject
if not hasattr(cls, parts[0]): if not hasattr(root, sections[0]):
# every internal node in the config tree is an instance of its own unique class
class SubObj(object): class SubObj(object):
pass _i_am_a_config_class = True
setattr(cls, parts[0], SubObj) setattr(root.__class__, sections[0], SubObj())
AddConfigVar('.'.join(parts[1:]), doc, thing, cls=getattr(cls, parts[0])) newroot = getattr(root, sections[0])
if not getattr(newroot, '_i_am_a_config_class', False) or isinstance(newroot, type):
raise TypeError('Internal config nodes must be config class instances', newroot)
return AddConfigVar('.'.join(sections[1:]), doc, configparam, root=newroot)
else: else:
thing.doc = doc if hasattr(root, name):
thing.__get__() # trigger a read of the value raise AttributeError('This name is already taken', configparam.fullname)
setattr(cls, parts[0], thing) configparam.doc = doc
_config_var_list.append(thing) configparam.__get__() # trigger a read of the value from config files and env vars
setattr(root.__class__, sections[0], configparam)
_config_var_list.append(configparam)
class ConfigParam(object): class ConfigParam(object):
def __init__(self, default, filter=None): def __init__(self, default, filter=None):
self.default = default self.default = default
self.filter=filter self.filter=filter
# there is a name attribute too, but it is set by AddConfigVar # N.B. --
# self.fullname # set by AddConfigVar
# self.doc # set by AddConfigVar
def __get__(self, *args): def __get__(self, *args):
#print "GETTING PARAM", self.fullname, self, args #print "GETTING PARAM", self.fullname, self, args
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论