Ejemplo n.º 1
0
 def visit_content_in_condition_control(self, node, level):
     if isinstance(node, ast.Expr):
         self.visit_Expr(node, level)
     elif isinstance(node, ast.Assert):
         self.visit_Assert(node, level)
     elif isinstance(node, ast.Assign):
         self.visit_Assign(node, level)
     elif isinstance(node, ast.AugAssign):
         self.visit_AugAssign(node, level)
     elif isinstance(node, ast.If):
         self.visit_If(node, level)
     elif isinstance(node, ast.For):
         self.visit_For(node, level)
     elif isinstance(node, ast.While):
         self.visit_While(node, level)
     elif isinstance(node, ast.Call):
         self.visit_Call(node, level)
     elif isinstance(node, ast.Raise):
         self.visit_Raise(node, level)
     elif isinstance(node, ast.Return):
         self.visit_Return(node, level)
     else:
         code = tools.ast2code(ast.fix_missing_locations(node))
         raise errors.CodeError(f'BrainPy does not support {type(node)} '
                                f'in Numba backend.\n\n{code}')
Ejemplo n.º 2
0
def _analyze_cls_func(host,
                      code,
                      show_code,
                      self_name=None,
                      pop_self=True,
                      **jit_setting):
    """Analyze the bounded function of one object.

  Parameters
  ----------
  host : Base
    The data host.
  code : str
    The function source code.
  self_name : optional, str
    The class name, like "self", "cls".
  show_code : bool
  """
    # arguments
    tree = ast.parse(code)
    if self_name is None:
        self_name = tree.body[0].args.args[0].arg
        # data assigned by self.xx in line right
        if self_name not in CLASS_KEYWORDS:
            raise errors.CodeError(
                f'BrainPy only support class keyword '
                f'{CLASS_KEYWORDS}, but we got {self_name}.')
    if pop_self:
        tree.body[0].args.args.pop(0)  # remove "self" etc. class argument

    # analyze function body
    r = _analyze_cls_func_body(host=host,
                               self_name=self_name,
                               code=code,
                               tree=tree,
                               show_code=show_code,
                               has_func_def=True,
                               **jit_setting)
    code, arguments, arg2call, nodes, code_scope = r

    return code, arguments, arg2call, nodes, code_scope
Ejemplo n.º 3
0
 def visit_Delete(self, node):
     raise errors.CodeError(
         'Do not support "del" operation in Numba backend.')
Ejemplo n.º 4
0
 def visit_With(self, node):
     raise errors.CodeError('Do not support "with" block in Numba backend.')
Ejemplo n.º 5
0
 def visit_Try(self, node):
     raise errors.CodeError(
         'Do not support "try" handler in Numba backend.')
Ejemplo n.º 6
0
    def visit_Call(self, node, level=0):
        if getattr(node, 'starargs', None) is not None:
            raise ValueError("Variable number of arguments not supported")
        if getattr(node, 'kwargs', None) is not None:
            raise ValueError("Keyword arguments not supported")

        if node in self.visited_calls:
            return node

        calls = self.visit_attr(node.func)
        calls = calls[::-1]

        # get the object and the function
        if calls[0] not in backend.CLASS_KEYWORDS:
            return node
        obj = self.host
        for data in calls[1:-1]:
            obj = getattr(obj, data)
        obj_func = getattr(obj, calls[-1])

        # get function arguments
        args = []
        for arg in node.args:
            args.append(tools.ast2code(ast.fix_missing_locations(arg)))
        kw_args = OrderedDict()
        for keyword in node.keywords:
            kw_args[keyword.arg] = tools.ast2code(
                ast.fix_missing_locations(keyword.value))

        # TASK 1 : extract delay push and delay pull
        # ------
        # Replace the delay function call to the delay_data
        # index. In such a way, delay function will be removed.
        # ------

        if calls[-1] in ['push', 'pull'] and isinstance(
                obj, delays.ConstantDelay) and callable(obj_func):
            dvar4call = '.'.join(calls[0:-1])
            uniform_delay = getattr(obj, 'uniform_delay')
            if calls[-1] == 'push':
                data_need_pass = [
                    f'{dvar4call}.delay_data', f'{dvar4call}.delay_in_idx'
                ]
                idx_or_val = kw_args['idx_or_val'] if len(
                    args) == 0 else args[0]
                if len(args) + len(kw_args) == 1:
                    rep_expression = f'{dvar4call}.delay_data[{dvar4call}.delay_in_idx] = {idx_or_val}'
                elif len(args) + len(kw_args) == 2:
                    value = kw_args['value'] if len(args) <= 1 else args[1]
                    if uniform_delay:
                        rep_expression = f'{dvar4call}.delay_data[{dvar4call}.delay_in_idx, {idx_or_val}] = {value}'
                    else:
                        rep_expression = f'{dvar4call}.delay_data[{dvar4call}.delay_in_idx[{idx_or_val}], {idx_or_val}] = {value}'
                else:
                    raise errors.CodeError(
                        f'Cannot analyze the code: \n\n'
                        f'{tools.ast2code(ast.fix_missing_locations(node))}')
            else:
                data_need_pass = [
                    f'{dvar4call}.delay_data', f'{dvar4call}.delay_out_idx'
                ]
                if len(args) + len(kw_args) == 0:
                    rep_expression = f'{dvar4call}.delay_data[{dvar4call}.delay_out_idx]'
                elif len(args) + len(kw_args) == 1:
                    idx = kw_args['idx'] if len(args) == 0 else args[0]
                    if uniform_delay:
                        rep_expression = f'{dvar4call}.delay_data[{dvar4call}.delay_out_idx, {idx}]'
                    else:
                        rep_expression = f'{dvar4call}.delay_data[{dvar4call}.delay_out_idx[{idx}], {idx}]'
                else:
                    raise errors.CodeError(
                        f'Cannot analyze the code: \n\n'
                        f'{tools.ast2code(ast.fix_missing_locations(node))}')

            org_call = tools.ast2code(ast.fix_missing_locations(node))
            self.visited_calls[node] = dict(type=calls[-1],
                                            org_call=org_call,
                                            rep_call=rep_expression,
                                            data_need_pass=data_need_pass)

        self.generic_visit(node)
Ejemplo n.º 7
0
def check_kws(parameters, keywords):
  for key, meaning in keywords.items():
    if key in parameters:
      raise errors.CodeError(f'"{key}" is a keyword for '
                             f'numerical solvers in BrainPy, denoting '
                             f'"{meaning}". Please change another name.')