Skip to content

Commit

Permalink
Made CodeObject Nameable and gave better names to created CodeObjects
Browse files Browse the repository at this point in the history
  • Loading branch information
thesamovar committed Aug 20, 2013
1 parent ed5ec94 commit e3f1854
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 37 deletions.
2 changes: 2 additions & 0 deletions brian2/codegen/_prefs.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .codeobject import CodeObject
from brian2.core.preferences import brian_prefs, BrianPreference

# Preferences
Expand All @@ -19,5 +20,6 @@
Or it can be a ``CodeObject`` class.
''',
validator=lambda target: isinstance(target, str) or issubclass(target, CodeObject),
),
)
11 changes: 8 additions & 3 deletions brian2/codegen/codeobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
StochasticVariable)
from .functions.base import Function
from brian2.core.preferences import brian_prefs
from brian2.core.names import Nameable, find_name
from brian2.utils.logger import get_logger
from .translation import translate
from .runtime.targets import runtime_targets
Expand Down Expand Up @@ -79,11 +80,14 @@ def create_codeobject(name, abstract_code, namespace, variables, template_name,
iterate_all=iterate_all)
template_kwds.update(kwds)
logger.debug(name + " inner code:\n" + str(innercode))

name = find_name(name)

code = template(innercode, **template_kwds)
logger.debug(name + " code:\n" + str(code))

variables.update(indices)
codeobj = codeobj_class(code, namespace, variables)
codeobj = codeobj_class(code, namespace, variables, name=name)
codeobj.compile()
return codeobj

Expand All @@ -97,7 +101,7 @@ def get_codeobject_template(name, codeobj_class=None):
return getattr(codeobj_class.templater, name)


class CodeObject(object):
class CodeObject(Nameable):
'''
Executable code object.
Expand All @@ -114,7 +118,8 @@ class CodeObject(object):
#: The `Language` used by this `CodeObject`
language = None

def __init__(self, code, namespace, variables):
def __init__(self, code, namespace, variables, name='codeobject*'):
Nameable.__init__(self, name=name)
self.code = code
self.compile_methods = self.get_compile_methods(variables)
self.namespace = namespace
Expand Down
4 changes: 2 additions & 2 deletions brian2/codegen/runtime/numpy_rt/numpy_rt.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ class NumpyCodeObject(CodeObject):
'templates'))
language = NumpyLanguage()

def __init__(self, code, namespace, variables):
def __init__(self, code, namespace, variables, name='numpy_code_object*'):
# TODO: This should maybe go somewhere else
namespace['logical_not'] = np.logical_not
CodeObject.__init__(self, code, namespace, variables)
CodeObject.__init__(self, code, namespace, variables, name=name)

def compile(self):
super(NumpyCodeObject, self).compile()
Expand Down
4 changes: 2 additions & 2 deletions brian2/codegen/runtime/weave_rt/weave_rt.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ class WeaveCodeObject(CodeObject):
'templates'))
language = CPPLanguage(c_data_type=weave_data_type)

def __init__(self, code, namespace, variables):
super(WeaveCodeObject, self).__init__(code, namespace, variables)
def __init__(self, code, namespace, variables, name='weave_code_object*'):
super(WeaveCodeObject, self).__init__(code, namespace, variables, name=name)
self.compiler = brian_prefs['codegen.runtime.weave.compiler']
self.extra_compile_args = brian_prefs['codegen.runtime.weave.extra_compile_args']

Expand Down
52 changes: 28 additions & 24 deletions brian2/core/names.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,35 @@
from brian2.utils.logger import get_logger
from brian2.core.tracking import Trackable
import re

__all__ = ['Nameable']

logger = get_logger(__name__)


def find_name(name):
if name.endswith('*'):
name = name[:-1]
wildcard = True
else:
wildcard = False
instances = set(Nameable.__instances__())
allnames = set(obj().name for obj in instances
if hasattr(obj(), 'name'))

# Try the name without any additions first:
if name not in allnames:
return name
elif not wildcard:
raise ValueError("An object with name "+name+" is already defined.")

# Name is already taken, try _1, _2, etc.
i = 1
while name+'_'+str(i) in allnames:
i += 1
return name+'_'+str(i)


class Nameable(Trackable):
'''
Base class to find a unique name for an object
Expand All @@ -28,35 +52,15 @@ class Nameable(Trackable):
------
ValueError
If the name is already taken.
'''
def _find_name(self, name):
if name.endswith('*'):
name = name[:-1]
wildcard = True
else:
wildcard = False
instances = set(Nameable.__instances__())
allnames = set(obj().name for obj in instances
if hasattr(obj(), 'name'))

# Try the name without any additions first:
if name not in allnames:
return name
elif not wildcard:
raise ValueError("An object with name "+name+" is already defined.")

# Name is already taken, try _1, _2, etc.
i = 1
while name+'_'+str(i) in allnames:
i += 1
return name+'_'+str(i)

'''
def __init__(self, name):
if not isinstance(name, basestring):
raise TypeError(('"name" argument has to be a string, is type '
'{type} instead').format(type=repr(type(name))))
if not re.match(r"[_A-Za-z][_a-zA-Z0-9]*\*?$", name):
raise ValueError("Name %s not valid variable name" % name)

self._name = self._find_name(name)
self._name = find_name(name)
logger.debug("Created object of class "+self.__class__.__name__+" with name "+self._name)

name = property(fget=lambda self:self._name,
Expand Down
6 changes: 3 additions & 3 deletions brian2/groups/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,9 @@ def create_runner_codeobj(group, code, template_name, indices=None,

if name is None:
if group is not None:
name = group.name + '_codeobject*'
name = '%s_%s_codeobject*' % (group.name, template_name)
else:
name = '_codeobject*'
name = '%s_codeobject*' % template_name

if indices is None:
indices = group.indices
Expand Down Expand Up @@ -446,7 +446,7 @@ def pre_run(self, namespace):
additional_variables, namespace)
self.codeobj = create_runner_codeobj(self.group, self.abstract_code,
self.template,
name=self.name,
name=self.name+'_codeobject*',
check_units=self.check_units,
additional_variables=additional_variables,
additional_namespace=namespace,
Expand Down
2 changes: 1 addition & 1 deletion brian2/monitors/ratemonitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def reinit(self):
np.dtype(type(self.clock.t))))

def pre_run(self, namespace):
self.codeobj = create_codeobject(self.name,
self.codeobj = create_codeobject(self.name+'_codeobject*',
'', # No model-specific code
{}, # no namespace
self.variables,
Expand Down
2 changes: 1 addition & 1 deletion brian2/monitors/spikemonitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def reinit(self):
self.count = np.zeros(len(self.source), dtype=int)

def pre_run(self, namespace):
self.codeobj = create_codeobject(self.name,
self.codeobj = create_codeobject(self.name+'_codeobject*',
'', # No model-specific code
{}, # no namespace
self.variables,
Expand Down
2 changes: 1 addition & 1 deletion brian2/monitors/statemonitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ def pre_run(self, namespace):
self.codeobj = create_runner_codeobj(self.source,
code,
'statemonitor',
name=self.name,
name=self.name+'_codeobject*',
additional_variables=self.variables,
additional_namespace=namespace,
template_kwds={'_variable_names':
Expand Down
4 changes: 4 additions & 0 deletions brian2/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ def run():

dirname = os.path.join(os.path.dirname(__file__), '..')
return nose.run(argv=['', dirname, '--with-doctest'])

if __name__=='__main__':
run()

0 comments on commit e3f1854

Please sign in to comment.