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
示例#2
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
示例#3
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 += '.. _angela-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
示例#4
0
 def __str__(self):
     s = ''
     for k, v in list(self._templates.items()):
         s += k + ':\n'
         s += strip_empty_lines(indent(v)) + '\n'
     return s
 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
示例#6
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
   :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/angela-team/angela2-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".
'''
示例#8
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
示例#9
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 angela2.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.values():
        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) from 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.items():
        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.items():
        if isinstance(value, Function):
            try:
                value.implementations[codeobj_class]
            except KeyError as ex:
                # if we are dealing with numpy, add the default implementation
                from angela2.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)) from ex

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

    # Add the indices needed by the variables
    for varname in list(variables):
        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)