Example #1
0
def codeprint(code):
    if isinstance(code, str):
        print deindent(code)
    else:
        for k, v in code.items():
            print k+':'
            print indent(deindent(v))
Example #2
0
    def code_object(self, owner, name, abstract_code, variables, template_name,
                    variable_indices, codeobj_class=None,
                    template_kwds=None, override_conditional_write=None,
                    compiler_kwds=None):
        if compiler_kwds is None:
            compiler_kwds = {}
        name = find_name(name)
        codeobj_class = self.code_object_class(codeobj_class)
        template = getattr(codeobj_class.templater, template_name)
        iterate_all = template.iterate_all
        generator = codeobj_class.generator_class(variables=variables,
                                                  variable_indices=variable_indices,
                                                  owner=owner,
                                                  iterate_all=iterate_all,
                                                  codeobj_class=codeobj_class,
                                                  override_conditional_write=override_conditional_write,
                                                  allows_scalar_write=template.allows_scalar_write,
                                                  name=name,
                                                  template_name=template_name)
        if template_kwds is None:
            template_kwds = dict()
        else:
            template_kwds = template_kwds.copy()

        logger.diagnostic('%s abstract code:\n%s' % (name, indent(code_representation(abstract_code))))

        scalar_code, vector_code, kwds = generator.translate(abstract_code,
                                                             dtype=prefs['core.default_float_dtype'])
        # Add the array names as keywords as well
        for varname, var in variables.items():
            if isinstance(var, ArrayVariable):
                pointer_name = generator.get_array_name(var)
                if var.scalar:
                    pointer_name += '[0]'
                template_kwds[varname] = pointer_name
                if hasattr(var, 'resize'):
                    dyn_array_name = generator.get_array_name(var,
                                                              access_data=False)
                    template_kwds['_dynamic_'+varname] = dyn_array_name


        template_kwds.update(kwds)
        logger.diagnostic('%s snippet (scalar):\n%s' % (name, indent(code_representation(scalar_code))))
        logger.diagnostic('%s snippet (vector):\n%s' % (name, indent(code_representation(vector_code))))

        code = template(scalar_code, vector_code,
                        owner=owner, variables=variables, codeobj_name=name,
                        variable_indices=variable_indices,
                        get_array_name=generator.get_array_name,
                        **template_kwds)
        logger.diagnostic('%s code:\n%s' % (name, indent(code_representation(code))))

        codeobj = codeobj_class(owner, code, variables, variable_indices,
                                template_name=template_name,
                                template_source=template.template_source,
                                name=name, compiler_kwds=compiler_kwds)
        codeobj.compile()
        return codeobj
Example #3
0
    def code_object(self, owner, name, abstract_code, variables, template_name,
                    variable_indices, codeobj_class=None,
                    template_kwds=None, override_conditional_write=None,
                    compiler_kwds=None):
        if compiler_kwds is None:
            compiler_kwds = {}
        name = find_name(name)
        codeobj_class = self.code_object_class(codeobj_class)
        template = getattr(codeobj_class.templater, template_name)
        iterate_all = template.iterate_all
        generator = codeobj_class.generator_class(variables=variables,
                                                  variable_indices=variable_indices,
                                                  owner=owner,
                                                  iterate_all=iterate_all,
                                                  codeobj_class=codeobj_class,
                                                  override_conditional_write=override_conditional_write,
                                                  allows_scalar_write=template.allows_scalar_write,
                                                  name=name,
                                                  template_name=template_name)
        if template_kwds is None:
            template_kwds = dict()
        else:
            template_kwds = template_kwds.copy()

        logger.diagnostic('%s abstract code:\n%s' % (name, indent(code_representation(abstract_code))))

        scalar_code, vector_code, kwds = generator.translate(abstract_code,
                                                             dtype=prefs['core.default_float_dtype'])
        # Add the array names as keywords as well
        for varname, var in variables.iteritems():
            if isinstance(var, ArrayVariable):
                pointer_name = generator.get_array_name(var)
                if var.scalar:
                    pointer_name += '[0]'
                template_kwds[varname] = pointer_name
                if hasattr(var, 'resize'):
                    dyn_array_name = generator.get_array_name(var,
                                                              access_data=False)
                    template_kwds['_dynamic_'+varname] = dyn_array_name


        template_kwds.update(kwds)
        logger.diagnostic('%s snippet (scalar):\n%s' % (name, indent(code_representation(scalar_code))))
        logger.diagnostic('%s snippet (vector):\n%s' % (name, indent(code_representation(vector_code))))

        code = template(scalar_code, vector_code,
                        owner=owner, variables=variables, codeobj_name=name,
                        variable_indices=variable_indices,
                        get_array_name=generator.get_array_name,
                        **template_kwds)
        logger.diagnostic('%s code:\n%s' % (name, indent(code_representation(code))))

        codeobj = codeobj_class(owner, code, variables, variable_indices,
                                template_name=template_name,
                                template_source=template.template_source,
                                name=name, compiler_kwds=compiler_kwds)
        codeobj.compile()
        return codeobj
Example #4
0
    def vectorise_code(self, statements, variables, variable_indices, index='_idx'):

        # We treat every statement individually with its own read and write code
        # to be on the safe side
        lines = []
        created_vars = {stmt.var for stmt in statements if stmt.op == ':='}
        for statement in statements:
            lines.append('#  Abstract code:  {var} {op} {expr}'.format(var=statement.var,
                                                                       op=statement.op,
                                                                       expr=statement.expr))
            read, write, indices, conditional_write_vars = self.arrays_helper([statement])
            try:
                # We make sure that we only add code to `lines` after it went
                # through completely
                ufunc_lines = []
                # No need to load a variable if it is only in read because of
                # the in-place operation
                if (statement.inplace and
                            variable_indices[statement.var] != '_idx' and
                            statement.var not in get_identifiers(statement.expr)):
                    read = read - {statement.var}
                ufunc_lines.extend(self.read_arrays(read, write, indices,
                                              variables, variable_indices))
                ufunc_lines.append(self.ufunc_at_vectorisation(statement,
                                                               variables,
                                                               variable_indices,
                                                               conditional_write_vars,
                                                               created_vars,
                                                               index=index))
                # Do not write back such values, the ufuncs have modified the
                # underlying array already
                if statement.inplace and variable_indices[statement.var] != '_idx':
                    write = write - {statement.var}
                ufunc_lines.extend(self.write_arrays([statement], read, write,
                                                     variables,
                                                     variable_indices))
                lines.extend(ufunc_lines)
            except VectorisationError:
                logger.warn("Failed to vectorise synapses code, falling back on Python loop: note that "
                            "this will be very slow! Switch to another code generation target for "
                            "best performance (e.g. cython or weave).",
                            once=True)
                lines.extend(['_full_idx = _idx',
                              'for _idx in _full_idx:'])
                lines.extend(indent(code) for code in
                             self.read_arrays(read, write, indices,
                                              variables, variable_indices))
                line = self.translate_statement(statement)
                line = self.conditional_write(line, statement, variables,
                                              conditional_write_vars,
                                              created_vars)
                lines.append(indent(line))
                lines.extend(indent(code) for code in
                             self.write_arrays(statements, read, write,
                                               variables, variable_indices))
                lines.append('_idx = _full_idx')

        return lines
    def translate_one_statement_sequence(self, statements, scalar=False):
        variables = self.variables
        variable_indices = self.variable_indices
        read, write, indices, conditional_write_vars = self.arrays_helper(statements)
        lines = []
        # index and read arrays (index arrays first)
        for varname in itertools.chain(indices, read):
            var = variables[varname]
            index = variable_indices[varname]
            line = '{varname} = {arrayname}[{index}]'.format(varname=varname, arrayname=self.get_array_name(var),
                                                             index=index)
            lines.append(line)
        # the actual code
        created_vars = set([])
        for stmt in statements:
            if stmt.op==':=':
                created_vars.add(stmt.var)
            line = self.translate_statement(stmt)
            if stmt.var in conditional_write_vars:
                subs = {}
                condvar = conditional_write_vars[stmt.var]
                lines.append('if %s:' % condvar)
                lines.append(indent(line))
            else:
                lines.append(line)
        # write arrays
        for varname in write:
            index_var = self.variable_indices[varname]
            var = self.variables[varname]
            line = self.get_array_name(var, self.variables) + '[' + index_var + '] = ' + varname
            lines.append(line)

        return lines
Example #6
0
    def translate_one_statement_sequence(self, statements, scalar=False):
        variables = self.variables
        variable_indices = self.variable_indices
        read, write, indices, conditional_write_vars = self.arrays_helper(statements)
        lines = []
        # index and read arrays (index arrays first)
        for varname in itertools.chain(indices, read):
            var = variables[varname]
            index = variable_indices[varname]
            line = '{varname} = {arrayname}[{index}]'.format(varname=varname, arrayname=self.get_array_name(var),
                                                             index=index)
            lines.append(line)
        # the actual code
        for stmt in statements:
            if stmt.op == ':=' and not stmt.var in variables:
                self.temporary_vars.add((stmt.var, stmt.dtype))
            line = self.translate_statement(stmt)
            if stmt.var in conditional_write_vars:
                subs = {}
                condvar = conditional_write_vars[stmt.var]
                lines.append('if %s:' % condvar)
                lines.append(indent(line))
            else:
                lines.append(line)
        # write arrays
        for varname in write:
            index_var = self.variable_indices[varname]
            var = self.variables[varname]
            line = self.get_array_name(var, self.variables) + '[' + index_var + '] = ' + varname
            lines.append(line)

        return lines
Example #7
0
def numerically_check_permutation_code(code):
    # numerically checks that a code block used in the test below is permutation-independent by creating a
    # presynaptic and postsynaptic group of 3 neurons each, and a full connectivity matrix between them, then
    # repeatedly filling in random values for each of the variables, and checking for several random shuffles of
    # the synapse order that the result doesn't depend on it. This is a sort of test of the test itself, to make
    # sure we didn't accidentally assign a good/bad example to the wrong class.
    code = deindent(code)
    from collections import defaultdict
    vars = get_identifiers(code)
    indices = defaultdict(lambda: '_idx')
    vals = {}
    for var in vars:
        if var.endswith('_syn'):
            indices[var] = '_idx'
            vals[var] = zeros(9)
        elif var.endswith('_pre'):
            indices[var] ='_presynaptic_idx'
            vals[var] = zeros(3)
        elif var.endswith('_post'):
            indices[var] = '_postsynaptic_idx'
            vals[var] = zeros(3)
    subs = dict((var, var+'['+idx+']') for var, idx in indices.iteritems())
    code = word_substitute(code, subs)
    code = '''
from numpy import *
from numpy.random import rand, randn
for _idx in shuffled_indices:
    _presynaptic_idx = presyn[_idx]
    _postsynaptic_idx = postsyn[_idx]
{code}
    '''.format(code=indent(code))
    ns = vals.copy()
    ns['shuffled_indices'] = arange(9)
    ns['presyn'] = arange(9)%3
    ns['postsyn'] = arange(9)/3
    for _ in xrange(10):
        origvals = {}
        for k, v in vals.iteritems():
            v[:] = randn(len(v))
            origvals[k] = v.copy()
        exec code in ns
        endvals = {}
        for k, v in vals.iteritems():
            endvals[k] = v.copy()
        for _ in xrange(10):
            for k, v in vals.iteritems():
                v[:] = origvals[k]
            shuffle(ns['shuffled_indices'])
            exec code in ns
            for k, v in vals.iteritems():
                try:
                    assert_allclose(v, endvals[k])
                except AssertionError:
                    raise OrderDependenceError()
Example #8
0
 def _get_documentation(self):
     s = ''
     for name in sorted(self._values.keys()):
         default = self._default_values[name]
         doc = str(self._docs[name])
         # Make a link target
         s += '.. _brian-pref-{name}:\n\n'.format(name=name.replace('_', '-'))
         s += '``{name}`` = ``{default}``\n'.format(name=name,
                                                    default=repr(default))
         s += indent(deindent(doc))
         s += '\n\n'
     return s
Example #9
0
 def translate_to_statements(self, statements, conditional_write_vars):
     lines = []
     for stmt in statements:
         if stmt.op == ':=' and not stmt.var in self.variables:
             self.temporary_vars.add((stmt.var, stmt.dtype))
         line = self.translate_statement(stmt)
         if stmt.var in conditional_write_vars:
             subs = {}
             condvar = conditional_write_vars[stmt.var]
             lines.append('if %s:' % condvar)
             lines.append(indent(line))
         else:
             lines.append(line)
     return lines
Example #10
0
 def translate_to_statements(self, statements, conditional_write_vars):
     lines = []
     for stmt in statements:
         if stmt.op == ':=' and not stmt.var in self.variables:
             self.temporary_vars.add((stmt.var, stmt.dtype))
         line = self.translate_statement(stmt)
         if stmt.var in conditional_write_vars:
             subs = {}
             condvar = conditional_write_vars[stmt.var]
             lines.append(f'if {condvar}:')
             lines.append(indent(line))
         else:
             lines.append(line)
     return lines
Example #11
0
    def _get_one_documentation(self, basename, link_targets):
        '''
        Document a single category of preferences.
        '''

        s = ''
        if not basename in self.pref_register:
            raise ValueError('No preferences under the name "%s" are registered' % basename)
        prefdefs, basedoc = self.pref_register[basename]
        s += deindent(basedoc, docstring=True).strip() + '\n\n'
        for name in sorted(prefdefs.keys()):
            pref = prefdefs[name]
            name = basename + '.' + name
            linkname = name.replace('_', '-').replace('.', '-')
            if link_targets:
                # Make a link target
                s += '.. _brian-pref-{name}:\n\n'.format(name=linkname)
            s += '``{name}`` = ``{default}``\n'.format(name=name,
                                                       default=pref.representor(pref.default))
            s += indent(deindent(pref.docs, docstring=True))
            s += '\n\n'
        return s
Example #12
0
    def _get_one_documentation(self, basename, link_targets):
        '''
        Document a single category of preferences.
        '''

        s = ''
        if not basename in self.pref_register:
            raise ValueError('No preferences under the name "%s" are registered' % basename)
        prefdefs, basedoc = self.pref_register[basename]
        s += deindent(basedoc, docstring=True).strip() + '\n\n'
        for name in sorted(prefdefs.keys()):
            pref = prefdefs[name]
            name = basename + '.' + name
            linkname = name.replace('_', '-').replace('.', '-')
            if link_targets:
                # Make a link target
                s += '.. _brian-pref-{name}:\n\n'.format(name=linkname)
            s += '``{name}`` = ``{default}``\n'.format(name=name,
                                                       default=pref.representor(pref.default))
            s += indent(deindent(pref.docs, docstring=True))
            s += '\n\n'
        return s
Example #13
0
 def exceptions(self):
     exc_list = []
     for configuration in self.configurations:
         curconfig = []
         for ft in self.feature_tests:
             sym, txt, exc, tb = self.full_results[configuration.name,
                                                   ft.fullname()]
             if tb is not None:
                 curconfig.append((ft.fullname(), tb))
         if len(curconfig):
             exc_list.append((configuration.name, curconfig))
     if len(exc_list)==0:
         return ''
     r = ''
     s = 'Exceptions'
     r += s+'\n'+'-'*len(s)+'\n\n'
     for config_name, curconfig in exc_list:
         s = config_name
         r += s+'\n'+'^'*len(s)+'\n\n'
         for name, tb in curconfig:
             r += name+'::\n\n'+indent(tb)+'\n\n' 
     return r
Example #14
0
 def exceptions(self):
     exc_list = []
     for configuration in self.configurations:
         curconfig = []
         for ft in self.feature_tests:
             sym, txt, exc, tb, runtime, prof_info = self.full_results[
                 configuration.name, ft.fullname()]
             if tb is not None:
                 curconfig.append((ft.fullname(), tb))
         if len(curconfig):
             exc_list.append((configuration.name, curconfig))
     if len(exc_list) == 0:
         return ''
     r = ''
     s = 'Exceptions'
     r += s + '\n' + '-' * len(s) + '\n\n'
     for config_name, curconfig in exc_list:
         s = config_name
         r += s + '\n' + '^' * len(s) + '\n\n'
         for name, tb in curconfig:
             r += name + '::\n\n' + indent(tb) + '\n\n'
     return r
Example #15
0
    def _get_one_documentation(self, basename, link_targets):
        """
        Document a single category of preferences.
        """

        s = ''
        if not basename in self.pref_register:
            raise ValueError(
                f"No preferences under the name '{basename}' are registered")
        prefdefs, basedoc = self.pref_register[basename]
        s += deindent(basedoc, docstring=True).strip() + '\n\n'
        for name in sorted(prefdefs.keys()):
            pref = prefdefs[name]
            name = basename + '.' + name
            linkname = name.replace('_', '-').replace('.', '-')
            if link_targets:
                # Make a link target
                s += f".. _brian-pref-{linkname}:\n\n"
            s += f"``{name}`` = ``{pref.representor(pref.default)}``\n"
            s += indent(deindent(pref.docs, docstring=True))
            s += "\n\n"
        return s
Example #16
0
def apply_code_template(code, template, placeholder='%CODE%'):
    '''
    Inserts the string ``code`` into ``template`` at ``placeholder``.
    
    The ``code`` is deindented, and inserted into ``template`` with the
    indentation level at the place where ``placeholder`` appears. The
    placeholder should appear on its own line.
    
    All tab characters are replaced by four spaces.
    '''
    code = deindent(code)
    code = strip_empty_lines(code)
    template = template.replace('\t', ' '*4)
    lines = template.split('\n')
    newlines = []
    for line in lines:
        if placeholder in line:
            indentlevel = len(line)-len(line.lstrip())
            newlines.append(indent(code, indentlevel, tab=' '))
        else:
            newlines.append(line)
    return '\n'.join(newlines)
Example #17
0
    def code_object(self, owner, name, abstract_code, variables, template_name,
                    variable_indices, codeobj_class=None,
                    template_kwds=None, override_conditional_write=None):

        codeobj_class = self.code_object_class(codeobj_class)
        template = getattr(codeobj_class.templater, template_name)
        iterate_all = template.iterate_all
        generator = codeobj_class.generator_class(variables=variables,
                                                  variable_indices=variable_indices,
                                                  owner=owner,
                                                  iterate_all=iterate_all,
                                                  codeobj_class=codeobj_class,
                                                  override_conditional_write=override_conditional_write,
                                                  allows_scalar_write=template.allows_scalar_write,
                                                  name=name,
                                                  template_name=template_name)
        if template_kwds is None:
            template_kwds = dict()
        else:
            template_kwds = template_kwds.copy()

        # Check that all functions are available
        for varname, value in variables.iteritems():
            if isinstance(value, Function):
                try:
                    value.implementations[codeobj_class]
                except KeyError as ex:
                    # if we are dealing with numpy, add the default implementation
                    if codeobj_class is NumpyCodeObject:
                        value.implementations.add_numpy_implementation(value.pyfunc)
                    else:
                        raise NotImplementedError(('Cannot use function '
                                                   '%s: %s') % (varname, ex))

        logger.diagnostic('%s abstract code:\n%s' % (name, indent(code_representation(abstract_code))))

        scalar_code, vector_code, kwds = generator.translate(abstract_code,
                                                             dtype=prefs['core.default_float_dtype'])
        # Add the array names as keywords as well
        for varname, var in variables.iteritems():
            if isinstance(var, ArrayVariable):
                pointer_name = generator.get_array_name(var)
                if var.scalar:
                    pointer_name += '[0]'
                template_kwds[varname] = pointer_name
                if hasattr(var, 'resize'):
                    dyn_array_name = generator.get_array_name(var,
                                                              access_data=False)
                    template_kwds['_dynamic_'+varname] = dyn_array_name


        template_kwds.update(kwds)
        logger.diagnostic('%s snippet (scalar):\n%s' % (name, indent(code_representation(scalar_code))))
        logger.diagnostic('%s snippet (vector):\n%s' % (name, indent(code_representation(vector_code))))

        name = find_name(name)

        code = template(scalar_code, vector_code,
                        owner=owner, variables=variables, codeobj_name=name,
                        variable_indices=variable_indices,
                        get_array_name=generator.get_array_name,
                        **template_kwds)
        logger.diagnostic('%s code:\n%s' % (name, indent(code_representation(code))))

        codeobj = codeobj_class(owner, code, variables, variable_indices,
                                template_name=template_name,
                                template_source=template.template_source,
                                name=name)
        codeobj.compile()
        return codeobj
Example #18
0
 def vectorise_code(self,
                    statements,
                    variables,
                    variable_indices,
                    index='_idx'):
     created_vars = {stmt.var for stmt in statements if stmt.op == ':='}
     try:
         lines = []
         used_variables = set()
         for statement in statements:
             lines.append('#  Abstract code:  {var} {op} {expr}'.format(
                 var=statement.var, op=statement.op, expr=statement.expr))
             # We treat every statement individually with its own read and write code
             # to be on the safe side
             read, write, indices, conditional_write_vars = self.arrays_helper(
                 [statement])
             # We make sure that we only add code to `lines` after it went
             # through completely
             ufunc_lines = []
             # No need to load a variable if it is only in read because of
             # the in-place operation
             if (statement.inplace
                     and variable_indices[statement.var] != '_idx' and
                     statement.var not in get_identifiers(statement.expr)):
                 read = read - {statement.var}
             ufunc_lines.extend(
                 self.read_arrays(read, write, indices, variables,
                                  variable_indices))
             ufunc_lines.append(
                 self.ufunc_at_vectorisation(
                     statement,
                     variables,
                     variable_indices,
                     conditional_write_vars,
                     created_vars,
                     used_variables,
                 ))
             # Do not write back such values, the ufuncs have modified the
             # underlying array already
             if statement.inplace and variable_indices[
                     statement.var] != '_idx':
                 write = write - {statement.var}
             ufunc_lines.extend(
                 self.write_arrays([statement], read, write, variables,
                                   variable_indices))
             lines.extend(ufunc_lines)
     except VectorisationError:
         if self._use_ufunc_at_vectorisation:
             logger.info(
                 "Failed to vectorise code, falling back on Python loop: note that "
                 "this will be very slow! Switch to another code generation target for "
                 "best performance (e.g. cython). First line is: " +
                 str(statements[0]),
                 once=True)
         lines = []
         lines.extend([
             '_full_idx = _idx', 'for _idx in _full_idx:',
             '    _vectorisation_idx = _idx'
         ])
         read, write, indices, conditional_write_vars = self.arrays_helper(
             statements)
         lines.extend(
             indent(code) for code in self.read_arrays(
                 read, write, indices, variables, variable_indices))
         for statement in statements:
             line = self.translate_statement(statement)
             if statement.var in conditional_write_vars:
                 lines.append(
                     indent('if {}:'.format(
                         conditional_write_vars[statement.var])))
                 lines.append(indent(line, 2))
             else:
                 lines.append(indent(line))
         lines.extend(
             indent(code) for code in self.write_arrays(
                 statements, read, write, variables, variable_indices))
     return lines
Example #19
0
        code = '''
        _tmp_V = x
        V += _tmp_V*x*dt
        '''
    specifiers = {
        'V':ArrayVariable('_array_V', '_neuron_idx', float64),
        'I':ArrayVariable('_array_I', '_neuron_idx', float64),
        'x':Subexpression('-(V+I)/tau'),
        'tau':Value(float64),
        'dt':Value(float64),
        '_cond':OutputVariable(bool),
        #'_neuron_idx':Index(),
        '_neuron_idx':Index(all=False),
        }
    for lang in [
                 CLanguage(),
                 PythonLanguage(),
                 NumexprPythonLanguage()
                 ]:
        print lang.__class__.__name__
        print '='*len(lang.__class__.__name__)
        output = translate(code, specifiers, float64, lang)
        print 'OUTPUT CODE:'
        if isinstance(output, str):
            print indent(output)
        else:
            for k, v in output.items():
                print k+':'
                print indent(v)
        print
Example #20
0
def create_runner_codeobj(
    group,
    code,
    template_name,
    variable_indices=None,
    name=None,
    check_units=True,
    needed_variables=None,
    additional_variables=None,
    level=0,
    run_namespace=None,
    template_kwds=None,
    override_conditional_write=None,
):
    ''' Create a `CodeObject` for the execution of code in the context of a
    `Group`.

    Parameters
    ----------
    group : `Group`
        The group where the code is to be run
    code : str or dict of str
        The code to be executed.
    template_name : str
        The name of the template to use for the code.
    variable_indices : dict-like, optional
        A mapping from `Variable` objects to index names (strings).  If none is
        given, uses the corresponding attribute of `group`.
    name : str, optional
        A name for this code object, will use ``group + '_codeobject*'`` if
        none is given.
    check_units : bool, optional
        Whether to check units in the statement. Defaults to ``True``.
    needed_variables: list of str, optional
        A list of variables that are neither present in the abstract code, nor
        in the ``USES_VARIABLES`` statement in the template. This is only
        rarely necessary, an example being a `StateMonitor` where the
        names of the variables are neither known to the template nor included
        in the abstract code statements.
    additional_variables : dict-like, optional
        A mapping of names to `Variable` objects, used in addition to the
        variables saved in `group`.
    level : int, optional
        How far to go up in the stack to find the call frame.
    run_namespace : dict-like, optional
        An additional namespace that is used for variable lookup (if not
        defined, the implicit namespace of local variables is used).
    template_kwds : dict, optional
        A dictionary of additional information that is passed to the template.
    override_conditional_write: list of str, optional
        A list of variable names which are used as conditions (e.g. for
        refractoriness) which should be ignored.
    '''

    if isinstance(code, str):
        code = {None: code}
    msg = 'Creating code object (group=%s, template name=%s) for abstract code:\n' % (
        group.name, template_name)
    msg += indent(code_representation(code))
    logger.debug(msg)
    from brian2.devices import get_device
    device = get_device()

    if override_conditional_write is None:
        override_conditional_write = set([])
    else:
        override_conditional_write = set(override_conditional_write)

    if check_units:
        for c in code.values():
            check_code_units(c,
                             group,
                             additional_variables=additional_variables,
                             level=level + 1,
                             run_namespace=run_namespace)

    codeobj_class = device.code_object_class(group.codeobj_class)
    template = getattr(codeobj_class.templater, template_name)

    all_variables = dict(group.variables)
    if additional_variables is not None:
        all_variables.update(additional_variables)

    # Determine the identifiers that were used
    used_known = set()
    unknown = set()
    for v in code.values():
        _, uk, u = analyse_identifiers(v, all_variables, recursive=True)
        used_known |= uk
        unknown |= u

    logger.debug('Unknown identifiers in the abstract code: ' +
                 ', '.join(unknown))

    # Only pass the variables that are actually used
    variables = group.resolve_all(used_known | unknown,
                                  additional_variables=additional_variables,
                                  run_namespace=run_namespace,
                                  level=level + 1)

    conditional_write_variables = {}
    # Add all the "conditional write" variables
    for var in variables.itervalues():
        cond_write_var = getattr(var, 'conditional_write', None)
        if cond_write_var in override_conditional_write:
            continue
        if cond_write_var is not None and cond_write_var not in variables.values(
        ):
            if cond_write_var.name in variables:
                raise AssertionError(
                    ('Variable "%s" is needed for the '
                     'conditional write mechanism of variable '
                     '"%s". Its name is already used for %r.') %
                    (cond_write_var.name, var.name,
                     variables[cond_write_var.name]))
            conditional_write_variables[cond_write_var.name] = cond_write_var

    variables.update(conditional_write_variables)

    # Add variables that are not in the abstract code, nor specified in the
    # template but nevertheless necessary
    if needed_variables is None:
        needed_variables = []
    # Also add the variables that the template needs
    variables.update(
        group.resolve_all(
            set(needed_variables) | set(template.variables),
            additional_variables=additional_variables,
            run_namespace=run_namespace,
            level=level + 1,
            do_warn=False))  # no warnings for internally used variables

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

    all_variable_indices = copy.copy(group.variables.indices)
    if additional_variables is not None:
        all_variable_indices.update(additional_variables.indices)
    if variable_indices is not None:
        all_variable_indices.update(variable_indices)

    # Make "conditional write" variables use the same index as the variable
    # that depends on them
    for varname, var in variables.iteritems():
        cond_write_var = getattr(var, 'conditional_write', None)
        if cond_write_var is not None:
            all_variable_indices[
                cond_write_var.name] = all_variable_indices[varname]

    # Add the indices needed by the variables
    varnames = variables.keys()
    for varname in varnames:
        var_index = all_variable_indices[varname]
        if not var_index in ('_idx', '0'):
            variables[var_index] = all_variables[var_index]

    return device.code_object(
        owner=group,
        name=name,
        abstract_code=code,
        variables=variables,
        template_name=template_name,
        variable_indices=all_variable_indices,
        template_kwds=template_kwds,
        codeobj_class=group.codeobj_class,
        override_conditional_write=override_conditional_write,
    )
Example #21
0
 def __str__(self):
     s = 'def %s(%s):\n%s\n    return %s\n' % (self.name,
                                               ', '.join(self.args),
                                               indent(self.code),
                                               self.return_expr)
     return s
Example #22
0
def create_runner_codeobj(group, code, template_name,
                          user_code=None,
                          variable_indices=None,
                          name=None, check_units=True,
                          needed_variables=None,
                          additional_variables=None,
                          level=0,
                          run_namespace=None,
                          template_kwds=None,
                          override_conditional_write=None,
                          codeobj_class=None
                          ):
    ''' Create a `CodeObject` for the execution of code in the context of a
    `Group`.

    Parameters
    ----------
    group : `Group`
        The group where the code is to be run
    code : str or dict of str
        The code to be executed.
    template_name : str
        The name of the template to use for the code.
    user_code : str, optional
        The code that had been specified by the user before other code was
        added automatically. If not specified, will be assumed to be identical
        to ``code``.
    variable_indices : dict-like, optional
        A mapping from `Variable` objects to index names (strings).  If none is
        given, uses the corresponding attribute of `group`.
    name : str, optional
        A name for this code object, will use ``group + '_codeobject*'`` if
        none is given.
    check_units : bool, optional
        Whether to check units in the statement. Defaults to ``True``.
    needed_variables: list of str, optional
        A list of variables that are neither present in the abstract code, nor
        in the ``USES_VARIABLES`` statement in the template. This is only
        rarely necessary, an example being a `StateMonitor` where the
        names of the variables are neither known to the template nor included
        in the abstract code statements.
    additional_variables : dict-like, optional
        A mapping of names to `Variable` objects, used in addition to the
        variables saved in `group`.
    level : int, optional
        How far to go up in the stack to find the call frame.
    run_namespace : dict-like, optional
        An additional namespace that is used for variable lookup (if not
        defined, the implicit namespace of local variables is used).
    template_kwds : dict, optional
        A dictionary of additional information that is passed to the template.
    override_conditional_write: list of str, optional
        A list of variable names which are used as conditions (e.g. for
        refractoriness) which should be ignored.
    codeobj_class : class, optional
        The `CodeObject` class to run code with. If not specified, defaults to
        the `group`'s ``codeobj_class`` attribute.
    '''

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

    if user_code is None:
        user_code = code

    if isinstance(code, str):
        code = {None: code}
        user_code = {None: user_code}

    msg = 'Creating code object (group=%s, template name=%s) for abstract code:\n' % (group.name, template_name)
    msg += indent(code_representation(code))
    logger.debug(msg)
    from brian2.devices import get_device
    device = get_device()
    
    if override_conditional_write is None:
        override_conditional_write = set([])
    else:
        override_conditional_write = set(override_conditional_write)

    if check_units:
        for c in code.values():
            # This is the first time that the code is parsed, catch errors
            try:
                check_code_units(c, group,
                                 additional_variables=additional_variables,
                                 level=level+1,
                                 run_namespace=run_namespace)
            except (SyntaxError, KeyError, ValueError) as ex:
                error_msg = _error_msg(c, name)
                raise ValueError(error_msg + str(ex))

    if codeobj_class is None:
        codeobj_class = device.code_object_class(group.codeobj_class)
    else:
        codeobj_class = device.code_object_class(codeobj_class)

    template = getattr(codeobj_class.templater, template_name, None)
    if template is None:
        codeobj_class_name = codeobj_class.class_name or codeobj_class.__name__
        raise AttributeError(('"%s" does not provide a code generation '
                              'template "%s"') % (codeobj_class_name,
                                                  template_name))

    all_variables = dict(group.variables)
    if additional_variables is not None:
        all_variables.update(additional_variables)

    # Determine the identifiers that were used
    identifiers = set()
    user_identifiers = set()
    for v, u_v in zip(code.values(), user_code.values()):
        _, uk, u = analyse_identifiers(v, all_variables, recursive=True)
        identifiers |= uk | u
        _, uk, u = analyse_identifiers(u_v, all_variables, recursive=True)
        user_identifiers |= uk | u
    # Only pass the variables that are actually used
    variables = group.resolve_all(identifiers,
                                  user_identifiers,
                                  additional_variables=additional_variables,
                                  run_namespace=run_namespace,
                                  level=level+1)

    conditional_write_variables = {}
    # Add all the "conditional write" variables
    for var in variables.itervalues():
        cond_write_var = getattr(var, 'conditional_write', None)
        if cond_write_var in override_conditional_write:
            continue
        if cond_write_var is not None and cond_write_var not in variables.values():
            if cond_write_var.name in variables:
                raise AssertionError(('Variable "%s" is needed for the '
                                      'conditional write mechanism of variable '
                                      '"%s". Its name is already used for %r.') % (cond_write_var.name,
                                                                                   var.name,
                                                                                   variables[cond_write_var.name]))
            conditional_write_variables[cond_write_var.name] = cond_write_var

    variables.update(conditional_write_variables)

    # Add variables that are not in the abstract code, nor specified in the
    # template but nevertheless necessary
    if needed_variables is None:
        needed_variables = []
    # Also add the variables that the template needs
    variables.update(group.resolve_all(set(needed_variables) | set(template.variables),
                                       # template variables are not known to the user:
                                       user_identifiers=set(),
                                       additional_variables=additional_variables,
                                       run_namespace=run_namespace,
                                       level=level+1))

    all_variable_indices = copy.copy(group.variables.indices)
    if additional_variables is not None:
        all_variable_indices.update(additional_variables.indices)
    if variable_indices is not None:
        all_variable_indices.update(variable_indices)

    # Make "conditional write" variables use the same index as the variable
    # that depends on them
    for varname, var in variables.iteritems():
        cond_write_var = getattr(var, 'conditional_write', None)
        if cond_write_var is not None:
            all_variable_indices[cond_write_var.name] = all_variable_indices[varname]

    # Add the indices needed by the variables
    varnames = variables.keys()
    for varname in varnames:
        var_index = all_variable_indices[varname]
        if not var_index in ('_idx', '0'):
            variables[var_index] = all_variables[var_index]

    return device.code_object(owner=group,
                              name=name,
                              abstract_code=code,
                              variables=variables,
                              template_name=template_name,
                              variable_indices=all_variable_indices,
                              template_kwds=template_kwds,
                              codeobj_class=codeobj_class,
                              override_conditional_write=override_conditional_write,
                              )
Example #23
0
 def __str__(self):
     s = ''
     for k, v in self._templates.items():
         s += k+':\n'
         s += strip_empty_lines(indent(v))+'\n'
     return s
Example #24
0
 def __str__(self):
     s = 'def %s(%s):\n%s\n    return %s\n' % (self.name,
                                               ', '.join(self.args),
                                               indent(self.code),
                                               self.return_expr)
     return s
Example #25
0
   :maxdepth: 1
   :titlesonly:

'''
for tutorial, _ in tutorials:
    text += '   ' + tutorial + '\n'
text += '''
.. only:: html

    Interactive notebooks and files
    -------------------------------
'''
for tutorial, _ in tutorials:
    text += indent(
        deindent('''
    .. |launchbinder{tutid}| image:: http://mybinder.org/badge.svg
    .. _launchbinder{tutid}: http://mybinder.org:/repo/brian-team/brian2-binder/notebooks/tutorials/{tutorial}.ipynb
    '''.format(tutorial=tutorial, tutid=tutorial.replace('-', ''))))

text += '\n'
for tutorial, title in tutorials:
    text += '    * |launchbinder{tutid}|_ :download:`{title} <{tutorial}.ipynb>`\n'.format(
        title=title, tutorial=tutorial, tutid=tutorial.replace('-', ''))
text += '''

.. _`Jupyter Notebooks`: http://jupyter-notebook-beginner-guide.readthedocs.org/en/latest/what_is_jupyter.html
.. _`Jupyter`: http://jupyter.org/
.. _`Jupyter Notebook documentation`: http://jupyter.readthedocs.org/

.. [#] Formerly known as "IPython Notebooks".
'''
Example #26
0
def create_runner_codeobj(group,
                          code,
                          template_name,
                          run_namespace,
                          user_code=None,
                          variable_indices=None,
                          name=None,
                          check_units=True,
                          needed_variables=None,
                          additional_variables=None,
                          template_kwds=None,
                          override_conditional_write=None,
                          codeobj_class=None):
    ''' Create a `CodeObject` for the execution of code in the context of a
    `Group`.

    Parameters
    ----------
    group : `Group`
        The group where the code is to be run
    code : str or dict of str
        The code to be executed.
    template_name : str
        The name of the template to use for the code.
    run_namespace : dict-like
        An additional namespace that is used for variable lookup (either
        an explicitly defined namespace or one taken from the local
        context).
    user_code : str, optional
        The code that had been specified by the user before other code was
        added automatically. If not specified, will be assumed to be identical
        to ``code``.
    variable_indices : dict-like, optional
        A mapping from `Variable` objects to index names (strings).  If none is
        given, uses the corresponding attribute of `group`.
    name : str, optional
        A name for this code object, will use ``group + '_codeobject*'`` if
        none is given.
    check_units : bool, optional
        Whether to check units in the statement. Defaults to ``True``.
    needed_variables: list of str, optional
        A list of variables that are neither present in the abstract code, nor
        in the ``USES_VARIABLES`` statement in the template. This is only
        rarely necessary, an example being a `StateMonitor` where the
        names of the variables are neither known to the template nor included
        in the abstract code statements.
    additional_variables : dict-like, optional
        A mapping of names to `Variable` objects, used in addition to the
        variables saved in `group`.
    template_kwds : dict, optional
        A dictionary of additional information that is passed to the template.
    override_conditional_write: list of str, optional
        A list of variable names which are used as conditions (e.g. for
        refractoriness) which should be ignored.
    codeobj_class : class, optional
        The `CodeObject` class to run code with. If not specified, defaults to
        the `group`'s ``codeobj_class`` attribute.
    '''

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

    if user_code is None:
        user_code = code

    if isinstance(code, str):
        code = {None: code}
        user_code = {None: user_code}

    msg = 'Creating code object (group=%s, template name=%s) for abstract code:\n' % (
        group.name, template_name)
    msg += indent(code_representation(code))
    logger.diagnostic(msg)
    from brian2.devices import get_device
    device = get_device()

    if override_conditional_write is None:
        override_conditional_write = set([])
    else:
        override_conditional_write = set(override_conditional_write)

    if codeobj_class is None:
        codeobj_class = device.code_object_class(group.codeobj_class)
    else:
        codeobj_class = device.code_object_class(codeobj_class)

    template = getattr(codeobj_class.templater, template_name)
    template_variables = getattr(template, 'variables', None)

    all_variables = dict(group.variables)
    if additional_variables is not None:
        all_variables.update(additional_variables)

    # Determine the identifiers that were used
    identifiers = set()
    user_identifiers = set()
    for v, u_v in zip(code.values(), user_code.values()):
        _, uk, u = analyse_identifiers(v, all_variables, recursive=True)
        identifiers |= uk | u
        _, uk, u = analyse_identifiers(u_v, all_variables, recursive=True)
        user_identifiers |= uk | u

    # Add variables that are not in the abstract code, nor specified in the
    # template but nevertheless necessary
    if needed_variables is None:
        needed_variables = []
    # Resolve all variables (variables used in the code and variables needed by
    # the template)
    variables = group.resolve_all(
        identifiers | set(needed_variables) | set(template_variables),
        # template variables are not known to the user:
        user_identifiers=user_identifiers,
        additional_variables=additional_variables,
        run_namespace=run_namespace)
    # We raise this error only now, because there is some non-obvious code path
    # where Jinja tries to get a Synapse's "name" attribute via syn['name'],
    # which then triggers the use of the `group_get_indices` template which does
    # not exist for standalone. Putting the check for template == None here
    # means we will first raise an error about the unknown identifier which will
    # then make Jinja try syn.name
    if template is None:
        codeobj_class_name = codeobj_class.class_name or codeobj_class.__name__
        raise AttributeError(
            ('"%s" does not provide a code generation '
             'template "%s"') % (codeobj_class_name, template_name))

    conditional_write_variables = {}
    # Add all the "conditional write" variables
    for var in variables.itervalues():
        cond_write_var = getattr(var, 'conditional_write', None)
        if cond_write_var in override_conditional_write:
            continue
        if cond_write_var is not None:
            if (cond_write_var.name in variables
                    and not variables[cond_write_var.name] is cond_write_var):
                logger.diagnostic(('Variable "%s" is needed for the '
                                   'conditional write mechanism of variable '
                                   '"%s". Its name is already used for %r.') %
                                  (cond_write_var.name, var.name,
                                   variables[cond_write_var.name]))
            else:
                conditional_write_variables[
                    cond_write_var.name] = cond_write_var

    variables.update(conditional_write_variables)

    if check_units:
        for c in code.values():
            # This is the first time that the code is parsed, catch errors
            try:
                check_units_statements(c, variables)
            except (SyntaxError, ValueError) as ex:
                error_msg = _error_msg(c, name)
                raise ValueError(error_msg + str(ex))

    all_variable_indices = copy.copy(group.variables.indices)
    if additional_variables is not None:
        all_variable_indices.update(additional_variables.indices)
    if variable_indices is not None:
        all_variable_indices.update(variable_indices)

    # Make "conditional write" variables use the same index as the variable
    # that depends on them
    for varname, var in variables.iteritems():
        cond_write_var = getattr(var, 'conditional_write', None)
        if cond_write_var is not None:
            all_variable_indices[
                cond_write_var.name] = all_variable_indices[varname]

    # Add the indices needed by the variables
    varnames = variables.keys()
    for varname in varnames:
        var_index = all_variable_indices[varname]
        if not var_index in ('_idx', '0'):
            variables[var_index] = all_variables[var_index]

    return device.code_object(
        owner=group,
        name=name,
        abstract_code=code,
        variables=variables,
        template_name=template_name,
        variable_indices=all_variable_indices,
        template_kwds=template_kwds,
        codeobj_class=codeobj_class,
        override_conditional_write=override_conditional_write,
    )
Example #27
0
 def __str__(self):
     s = ''
     for k, v in self._templates.items():
         s += k + ':\n'
         s += strip_empty_lines(indent(v)) + '\n'
     return s
Example #28
0
   :maxdepth: 1
   :titlesonly:

'''
for tutorial, _ in tutorials:
    text += '   ' + tutorial + '\n'
text += '''
.. only:: html

    Interactive notebooks and files
    -------------------------------
'''
for tutorial, _ in tutorials:
    text += indent(
        deindent('''
    .. |launchbinder{tutid}| image:: http://mybinder.org/badge.svg
    .. _launchbinder{tutid}: https://mybinder.org/v2/gh/brian-team/brian2-binder/master?filepath=tutorials/{tutorial}.ipynb
    '''.format(tutorial=tutorial, tutid=tutorial.replace('-', ''))))

text += '\n'
for tutorial, title in tutorials:
    text += '    * |launchbinder{tutid}|_ :download:`{title} <{tutorial}.ipynb>`\n'.format(
        title=title, tutorial=tutorial, tutid=tutorial.replace('-', ''))
text += '''

.. _`Jupyter Notebooks`: http://jupyter-notebook-beginner-guide.readthedocs.org/en/latest/what_is_jupyter.html
.. _`Jupyter`: http://jupyter.org/
.. _`Jupyter Notebook documentation`: http://jupyter.readthedocs.org/

.. [#] Formerly known as "IPython Notebooks".
'''
Example #29
0
def create_runner_codeobj(group, code, template_name,
                          run_namespace,
                          user_code=None,
                          variable_indices=None,
                          name=None, check_units=True,
                          needed_variables=None,
                          additional_variables=None,
                          template_kwds=None,
                          override_conditional_write=None,
                          codeobj_class=None
                          ):
    ''' Create a `CodeObject` for the execution of code in the context of a
    `Group`.

    Parameters
    ----------
    group : `Group`
        The group where the code is to be run
    code : str or dict of str
        The code to be executed.
    template_name : str
        The name of the template to use for the code.
    run_namespace : dict-like
        An additional namespace that is used for variable lookup (either
        an explicitly defined namespace or one taken from the local
        context).
    user_code : str, optional
        The code that had been specified by the user before other code was
        added automatically. If not specified, will be assumed to be identical
        to ``code``.
    variable_indices : dict-like, optional
        A mapping from `Variable` objects to index names (strings).  If none is
        given, uses the corresponding attribute of `group`.
    name : str, optional
        A name for this code object, will use ``group + '_codeobject*'`` if
        none is given.
    check_units : bool, optional
        Whether to check units in the statement. Defaults to ``True``.
    needed_variables: list of str, optional
        A list of variables that are neither present in the abstract code, nor
        in the ``USES_VARIABLES`` statement in the template. This is only
        rarely necessary, an example being a `StateMonitor` where the
        names of the variables are neither known to the template nor included
        in the abstract code statements.
    additional_variables : dict-like, optional
        A mapping of names to `Variable` objects, used in addition to the
        variables saved in `group`.
    template_kwds : dict, optional
        A dictionary of additional information that is passed to the template.
    override_conditional_write: list of str, optional
        A list of variable names which are used as conditions (e.g. for
        refractoriness) which should be ignored.
    codeobj_class : class, optional
        The `CodeObject` class to run code with. If not specified, defaults to
        the `group`'s ``codeobj_class`` attribute.
    '''

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

    if user_code is None:
        user_code = code

    if isinstance(code, str):
        code = {None: code}
        user_code = {None: user_code}

    msg = 'Creating code object (group=%s, template name=%s) for abstract code:\n' % (group.name, template_name)
    msg += indent(code_representation(code))
    logger.diagnostic(msg)
    from brian2.devices import get_device
    device = get_device()
    
    if override_conditional_write is None:
        override_conditional_write = set([])
    else:
        override_conditional_write = set(override_conditional_write)

    if codeobj_class is None:
        codeobj_class = device.code_object_class(group.codeobj_class)
    else:
        codeobj_class = device.code_object_class(codeobj_class)

    template = getattr(codeobj_class.templater, template_name)
    template_variables = getattr(template, 'variables', None)

    all_variables = dict(group.variables)
    if additional_variables is not None:
        all_variables.update(additional_variables)

    # Determine the identifiers that were used
    identifiers = set()
    user_identifiers = set()
    for v, u_v in zip(code.values(), user_code.values()):
        _, uk, u = analyse_identifiers(v, all_variables, recursive=True)
        identifiers |= uk | u
        _, uk, u = analyse_identifiers(u_v, all_variables, recursive=True)
        user_identifiers |= uk | u

    # Add variables that are not in the abstract code, nor specified in the
    # template but nevertheless necessary
    if needed_variables is None:
        needed_variables = []
    # Resolve all variables (variables used in the code and variables needed by
    # the template)
    variables = group.resolve_all(identifiers | set(needed_variables) | set(template_variables),
                                  # template variables are not known to the user:
                                  user_identifiers=user_identifiers,
                                  additional_variables=additional_variables,
                                  run_namespace=run_namespace)
    # We raise this error only now, because there is some non-obvious code path
    # where Jinja tries to get a Synapse's "name" attribute via syn['name'],
    # which then triggers the use of the `group_get_indices` template which does
    # not exist for standalone. Putting the check for template == None here
    # means we will first raise an error about the unknown identifier which will
    # then make Jinja try syn.name
    if template is None:
        codeobj_class_name = codeobj_class.class_name or codeobj_class.__name__
        raise AttributeError(('"%s" does not provide a code generation '
                              'template "%s"') % (codeobj_class_name,
                                                  template_name))


    conditional_write_variables = {}
    # Add all the "conditional write" variables
    for var in variables.itervalues():
        cond_write_var = getattr(var, 'conditional_write', None)
        if cond_write_var in override_conditional_write:
            continue
        if cond_write_var is not None:
            if (cond_write_var.name in variables and
                    not variables[cond_write_var.name] is cond_write_var):
                logger.diagnostic(('Variable "%s" is needed for the '
                                   'conditional write mechanism of variable '
                                   '"%s". Its name is already used for %r.') % (cond_write_var.name,
                                                                                var.name,
                                                                                variables[cond_write_var.name]))
            else:
                conditional_write_variables[cond_write_var.name] = cond_write_var

    variables.update(conditional_write_variables)

    if check_units:
        for c in code.values():
            # This is the first time that the code is parsed, catch errors
            try:
                check_units_statements(c, variables)
            except (SyntaxError, ValueError) as ex:
                error_msg = _error_msg(c, name)
                raise ValueError(error_msg + str(ex))

    all_variable_indices = copy.copy(group.variables.indices)
    if additional_variables is not None:
        all_variable_indices.update(additional_variables.indices)
    if variable_indices is not None:
        all_variable_indices.update(variable_indices)

    # Make "conditional write" variables use the same index as the variable
    # that depends on them
    for varname, var in variables.iteritems():
        cond_write_var = getattr(var, 'conditional_write', None)
        if cond_write_var is not None:
            all_variable_indices[cond_write_var.name] = all_variable_indices[varname]

    # Check that all functions are available
    for varname, value in variables.iteritems():
        if isinstance(value, Function):
            try:
                value.implementations[codeobj_class]
            except KeyError as ex:
                # if we are dealing with numpy, add the default implementation
                from brian2.codegen.runtime.numpy_rt import NumpyCodeObject
                if codeobj_class is NumpyCodeObject:
                    value.implementations.add_numpy_implementation(value.pyfunc)
                else:
                    raise NotImplementedError(('Cannot use function '
                                               '%s: %s') % (varname, ex))

    # Gather the additional compiler arguments declared by function
    # implementations
    all_keywords = [_gather_compiler_kwds(var, codeobj_class)
                    for var in variables.itervalues()
                    if isinstance(var, Function)]
    compiler_kwds = _merge_compiler_kwds(all_keywords)

    # Add the indices needed by the variables
    varnames = variables.keys()
    for varname in varnames:
        var_index = all_variable_indices[varname]
        if not var_index in ('_idx', '0'):
            variables[var_index] = all_variables[var_index]

    return device.code_object(owner=group,
                              name=name,
                              abstract_code=code,
                              variables=variables,
                              template_name=template_name,
                              variable_indices=all_variable_indices,
                              template_kwds=template_kwds,
                              codeobj_class=codeobj_class,
                              override_conditional_write=override_conditional_write,
                              compiler_kwds=compiler_kwds
                              )
Example #30
0
.. toctree::
   :maxdepth: 1
   :titlesonly:

'''
for tutorial, _ in tutorials:
    text += '   ' + tutorial + '\n'
text += '''
.. only:: html

    Interactive notebooks and files
    -------------------------------
'''
for tutorial, _ in tutorials:
    text += indent(deindent('''
    .. |launchbinder{tutid}| image:: http://mybinder.org/badge.svg
    .. _launchbinder{tutid}: http://mybinder.org:/repo/brian-team/brian2-binder/notebooks/tutorials/{tutorial}.ipynb
    '''.format(tutorial=tutorial, tutid=tutorial.replace('-', ''))))

text += '\n'
for tutorial, title in tutorials:
    text += '    * |launchbinder{tutid}|_ :download:`{title} <{tutorial}.ipynb>`\n'.format(title=title,
                                                tutorial=tutorial, tutid=tutorial.replace('-', ''))
text += '''

.. _`Jupyter Notebooks`: http://jupyter-notebook-beginner-guide.readthedocs.org/en/latest/what_is_jupyter.html
.. _`Jupyter`: http://jupyter.org/
.. _`Jupyter Notebook documentation`: http://jupyter.readthedocs.org/

.. [#] Formerly known as "IPython Notebooks".
'''
with open(os.path.join(target_dir, 'index.rst'), 'w') as f: