示例#1
0
    def visit_RaiseNode(self, node):
        if self.nopython:
            result = self._trap(node)
        else:
            result = self._raise_exception(node)

        return ast.Suite(body=result + [nodes.PropagateNode()])
示例#2
0
    def visit_RaiseNode(self, node):
        body = []
        if self.nopython:
            self._trap(body, node)
        else:
            self._raise_exception(body, node)

        body.append(nodes.PropagateNode())
        return ast.Suite(body=body)
示例#3
0
    def allocate_struct_on_stack(self, assmnt_node, target):
        # Allocate struct on stack
        temp = nodes.TempNode(target.type)
        assmnt_node.targets[0] = temp.store()
        assmnt_node.value = self.visit(assmnt_node.value)

        # Expose LLVM value through SSA (patch the Variable or the
        # LHS). We need to store the pointer to the struct (the alloca)
        ssa_assmnt = ast.Assign(targets=[target], value=temp.store())

        return ast.Suite(body=[assmnt_node, ssa_assmnt])
示例#4
0
def template(s, substitutions):
    s = textwrap.dedent(s)
    replaced = [0]

    def replace(ident):
        replaced[0] += 1
        return '%s%s' % (prefix, ident.group(1))

    source = re.sub('{{(.*?)}}', replace, s)
    tree = ast.parse(source)

    if replaced:
        tree = Interpolate(substitutions).visit(tree)

    return ast.Suite(body=tree.body)
示例#5
0
文件: fold.py 项目: winex/pystream
def foldSwitch(node):
    # Note: condtion.conditional may be killed, as
    # it is assumed to be a reference.

    # Constant value
    cond = node.condition.conditional
    if existingConstant(cond):
        value = cond.object.pyobj
        taken = node.t if value else node.f
        return ast.Suite([node.condition.preamble, taken])

    # Switch does nothing.
    if not node.t.blocks and not node.f.blocks:
        return node.condition.preamble

    return node
示例#6
0
    def visit_For(self, node):
        node.iter = self.visit(node.iter)

        if not isinstance(node.iter, PrangeNode):
            self.visitchildren(node)
            return node

        self.error_check_prange(node)
        node.target = self.visit(node.target)

        self.prange += 1
        node.body = self.visitlist(node.body)
        self.prange -= 1

        # Create prange closure
        prange_node = node.iter
        create_prange_closure(self.env, prange_node, node.body, node.target)

        # setup glue code
        pre_loop = rewrite_prange(self.env, prange_node, node.target,
                                  self.locals, self.closures)
        post_loop = perform_reductions(self.context, prange_node)

        # infer glue code at the right place
        pre_loop_dont_infer = nodes.dont_infer(pre_loop)
        pre_loop_infer_now = nodes.infer_now(pre_loop, pre_loop_dont_infer)

        # infer the type of the struct of privates right after the loop
        allprivates = set(prange_node.privates) | set(prange_node.reductions)
        type = prange_node.privates_struct_type
        infer_privates_struct = VariableTypeInferingNode(allprivates, type)

        # Signal that we now have additional local variables
        self.invalidate_locals()

        return ast.Suite(body=[
            pre_loop_dont_infer, node, infer_privates_struct,
            pre_loop_infer_now, post_loop
        ])
示例#7
0
    def visit_Print(self, node):
        if self.nopython:
            printfunc = self._print_nopython
            dst_type = c_string_type
        else:
            printfunc = self._print
            dst_type = object_

        result = []

        if node.values:
            print_space = printfunc(nodes.const(" ", dst_type), node.dest)
            for value in node.values:
                result.append(printfunc(value, node.dest))
                result.append(print_space)

            if node.nl:
                result.pop() # pop last space

        if node.nl:
            result.append(printfunc(nodes.const("\n", dst_type), node.dest))

        return ast.Suite(body=self.visitlist(result))
示例#8
0
    def visit_For(self, node):
        while_node = make_while_from_for(node)

        test = nodes.const(True, bool_)
        while_node.test = test

        impl = loopimpl.find_iterator_impl(node)

        # Get the iterator, loop body, and the item
        iter = impl.getiter(self.context, node, self.llvm_module)
        body = impl.body(self.context, node, self.llvm_module)
        item = impl.next(self.context, node, self.llvm_module)

        # Coerce item to LHS and assign
        item = nodes.CoercionNode(item, node.target.type)
        target_assmnt = ast.Assign(targets=[node.target], value=item)

        # Update While node body
        body.insert(0, target_assmnt)
        while_node.body = body

        nodes.merge_cfg_in_while(while_node)

        return ast.Suite(body=[iter, while_node])
示例#9
0
文件: unparse.py 项目: sherfert/GTR
def as_ast(dct):
    """See https://docs.python.org/2/library/ast.html"""
    if dct['ast_type'] == "Module":
        return ast.Module(dct["body"])
    elif dct['ast_type'] == "Interactive":
        return ast.Interactive(dct["body"])
    elif dct['ast_type'] == "Expression":
        return ast.Expression(dct["body"])
    elif dct['ast_type'] == "Suite":
        return ast.Suite(dct["body"])
    elif dct['ast_type'] == "FunctionDef":
        return ast.FunctionDef(dct["name"], dct["args"], dct["body"],
                               dct["decorator_list"])
    elif dct['ast_type'] == "ClassDef":
        return ast.ClassDef(dct["name"], dct["bases"], dct["body"],
                            dct["decorator_list"])
    elif dct['ast_type'] == "Return":
        return ast.Return(dct["value"])
    elif dct['ast_type'] == "Delete":
        return ast.Delete(dct["targets"])
    elif dct['ast_type'] == "Assign":
        return ast.Assign(dct["targets"], dct["value"])
    elif dct['ast_type'] == "AugAssign":
        return ast.AugAssign(dct["target"], dct["op"], dct["value"])
    elif dct['ast_type'] == "Print":
        return ast.Print(dct["dest"], dct["values"], dct["nl"])
    elif dct['ast_type'] == "For":
        return ast.For(dct["target"], dct["iter"], dct["body"], dct["orelse"])
    elif dct['ast_type'] == "While":
        return ast.While(dct["test"], dct["body"], dct["orelse"])
    elif dct['ast_type'] == "If":
        return ast.If(dct["test"], dct["body"], dct["orelse"])
    elif dct['ast_type'] == "With":
        return ast.With(dct["context_expr"], dct["optional_vars"], dct["body"])
    elif dct['ast_type'] == "Raise":
        return ast.Raise(dct["type"], dct["inst"], dct["tback"])
    elif dct['ast_type'] == "TryExcept":
        return ast.TryExcept(dct["body"], dct["handlers"], dct["orelse"])
    elif dct['ast_type'] == "TryFinally":
        return ast.TryFinally(dct["body"], dct["finalbody"])
    elif dct['ast_type'] == "Assert":
        return ast.Assert(dct["test"], dct["msg"])
    elif dct['ast_type'] == "Import":
        return ast.Import(dct["names"])
    elif dct['ast_type'] == "ImportFrom":
        return ast.ImportFrom(dct["module"], dct["names"], dct["level"])
    elif dct['ast_type'] == "Exec":
        return ast.Exec(dct["body"], dct["globals"], dct["locals"])
    elif dct['ast_type'] == "Global":
        return ast.Global(dct["names"])
    elif dct['ast_type'] == "Expr":
        return ast.Expr(dct["value"])
    elif dct['ast_type'] == "Pass":
        return ast.Pass()
    elif dct['ast_type'] == "Break":
        return ast.Break()
    elif dct['ast_type'] == "Continue":
        return ast.Continue()
    elif dct['ast_type'] == "BoolOp":
        return ast.BoolOp(dct["op"], dct["values"])
    elif dct['ast_type'] == "BinOp":
        return ast.BinOp(dct["left"], dct["op"], dct["right"])
    elif dct['ast_type'] == "UnaryOp":
        return ast.UnaryOp(dct["op"], dct["operand"])
    elif dct['ast_type'] == "Lambda":
        return ast.Lambda(dct["args"], dct["body"])
    elif dct['ast_type'] == "IfExp":
        return ast.IfExp(dct["test"], dct["body"], dct["orelse"])
    elif dct['ast_type'] == "Dict":
        return ast.Dict(dct["keys"], dct["values"])
    elif dct['ast_type'] == "Set":
        return ast.Set(dct["elts"])
    elif dct['ast_type'] == "ListComp":
        return ast.ListComp(dct["elt"], dct["generators"])
    elif dct['ast_type'] == "SetComp":
        return ast.SetComp(dct["elt"], dct["generators"])
    elif dct['ast_type'] == "DictComp":
        return ast.DictComp(dct["key"], dct["value"], dct["generators"])
    elif dct['ast_type'] == "GeneratorExp":
        return ast.GeneratorExp(dct["elt"], dct["generators"])
    elif dct['ast_type'] == "Yield":
        return ast.Yield(dct["value"])
    elif dct['ast_type'] == "Compare":
        return ast.Compare(dct["left"], dct["ops"], dct["comparators"])
    elif dct['ast_type'] == "Call":
        return ast.Call(dct["func"], dct["args"], dct["keywords"],
                        dct["starargs"], dct["kwargs"])
    elif dct['ast_type'] == "Repr":
        return ast.Repr(dct["value"])
    elif dct['ast_type'] == "Num":
        return ast.Num(dct["n"])
    elif dct['ast_type'] == "Str":
        # Converting to ASCII
        return ast.Str(dct["s"].encode('ascii', 'ignore'))
    elif dct['ast_type'] == "Attribute":
        return ast.Attribute(dct["value"], dct["attr"], dct["ctx"])
    elif dct['ast_type'] == "Subscript":
        return ast.Subscript(dct["value"], dct["slice"], dct["ctx"])
    elif dct['ast_type'] == "Name":
        return ast.Name(dct["id"], dct["ctx"])
    elif dct['ast_type'] == "List":
        return ast.List(dct["elts"], dct["ctx"])
    elif dct['ast_type'] == "Tuple":
        return ast.Tuple(dct["elts"], dct["ctx"])
    elif dct['ast_type'] == "Load":
        return ast.Load()
    elif dct['ast_type'] == "Store":
        return ast.Store()
    elif dct['ast_type'] == "Del":
        return ast.Del()
    elif dct['ast_type'] == "AugLoad":
        return ast.AugLoad()
    elif dct['ast_type'] == "AugStore":
        return ast.AugStore()
    elif dct['ast_type'] == "Param":
        return ast.Param()
    elif dct['ast_type'] == "Ellipsis":
        return ast.Ellipsis()
    elif dct['ast_type'] == "Slice":
        return ast.Slice(dct["lower"], dct["upper"], dct["step"])
    elif dct['ast_type'] == "ExtSlice":
        return ast.ExtSlice(dct["dims"])
    elif dct['ast_type'] == "Index":
        return ast.Index(dct["value"])
    elif dct['ast_type'] == "And":
        return ast.And()
    elif dct['ast_type'] == "Or":
        return ast.Or()
    elif dct['ast_type'] == "Add":
        return ast.Add()
    elif dct['ast_type'] == "Sub":
        return ast.Sub()
    elif dct['ast_type'] == "Mult":
        return ast.Mult()
    elif dct['ast_type'] == "Div":
        return ast.Div()
    elif dct['ast_type'] == "Mod":
        return ast.Mod()
    elif dct['ast_type'] == "Pow":
        return ast.Pow()
    elif dct['ast_type'] == "LShift":
        return ast.LShift()
    elif dct['ast_type'] == "RShift":
        return ast.RShift()
    elif dct['ast_type'] == "BitOr":
        return ast.BitOr()
    elif dct['ast_type'] == "BitXor":
        return ast.BitXor()
    elif dct['ast_type'] == "BitAnd":
        return ast.BitAnd()
    elif dct['ast_type'] == "FloorDiv":
        return ast.FloorDiv()
    elif dct['ast_type'] == "Invert":
        return ast.Invert()
    elif dct['ast_type'] == "Not":
        return ast.Not()
    elif dct['ast_type'] == "UAdd":
        return ast.UAdd()
    elif dct['ast_type'] == "USub":
        return ast.USub()
    elif dct['ast_type'] == "Eq":
        return ast.Eq()
    elif dct['ast_type'] == "NotEq":
        return ast.NotEq()
    elif dct['ast_type'] == "Lt":
        return ast.Lt()
    elif dct['ast_type'] == "LtE":
        return ast.LtE()
    elif dct['ast_type'] == "Gt":
        return ast.Gt()
    elif dct['ast_type'] == "GtE":
        return ast.GtE()
    elif dct['ast_type'] == "Is":
        return ast.Is()
    elif dct['ast_type'] == "IsNot":
        return ast.IsNot()
    elif dct['ast_type'] == "In":
        return ast.In()
    elif dct['ast_type'] == "NotIn":
        return ast.NotIn()
    elif dct['ast_type'] == "comprehension":
        return ast.comprehension(dct["target"], dct["iter"], dct["ifs"])
    elif dct['ast_type'] == "ExceptHandler":
        return ast.ExceptHandler(dct["type"], dct["name"], dct["body"])
    elif dct['ast_type'] == "arguments":
        return ast.arguments(dct["args"], dct["vararg"], dct["kwarg"],
                             dct["defaults"])
    elif dct['ast_type'] == "keyword":
        return ast.keyword(dct["arg"], dct["value"])
    elif dct['ast_type'] == "alias":
        return ast.alias(dct["name"], dct["asname"])
    else:
        return dct
示例#10
0
 def test_Suite(self):
     self.verify(ast.Suite([ast.Pass()]), 'pass')
示例#11
0
    def rewrite_range_iteration(self, node):
        """
        Handle range iteration:

            for i in range(start, stop, step):
                ...

        becomes

            nsteps = compute_nsteps(start, stop, step)
            temp = 0

            while temp < nsteps:
                target = start + temp * step
                ...
                temp += 1
        """
        self.generic_visit(node)

        temp = nodes.TempNode(node.target.type, 'target_temp')
        nsteps = nodes.TempNode(Py_ssize_t, 'nsteps')
        start, stop, step = unpack_range_args(node.iter)

        if isinstance(step, nodes.ConstNode):
            have_step = step.pyval != 1
        else:
            have_step = True

        start, stop, step = [
            nodes.CloneableNode(n) for n in (start, stop, step)
        ]

        if have_step:
            compute_nsteps = """
                    $length = {{stop}} - {{start}}
                    {{nsteps}} = $length / {{step}}
                    if {{nsteps_load}} * {{step}} != $length: #$length % {{step}}:
                        # Test for truncation
                        {{nsteps}} = {{nsteps_load}} + 1
                    # print "nsteps", {{nsteps_load}}
                """
        else:
            compute_nsteps = "{{nsteps}} = {{stop}} - {{start}}"

        if node.orelse:
            else_clause = "else: {{else_body}}"
        else:
            else_clause = ""

        templ = textwrap.dedent("""
                %s
                {{temp}} = 0
                while {{temp_load}} < {{nsteps_load}}:
                    {{target}} = {{start}} + {{temp_load}} * {{step}}
                    {{body}}
                    {{temp}} = {{temp_load}} + 1
                %s
            """) % (textwrap.dedent(compute_nsteps), else_clause)

        # Leave the bodies empty, they are already analyzed
        body = ast.Suite(body=[])
        else_body = ast.Suite(body=[])

        #--------------------------------------------------------------------
        # Substitute template and infer types
        #--------------------------------------------------------------------

        result = self.run_template(templ,
                                   vars=dict(length=Py_ssize_t),
                                   start=start,
                                   stop=stop,
                                   step=step,
                                   nsteps=nsteps.store(),
                                   nsteps_load=nsteps.load(),
                                   temp=temp.store(),
                                   temp_load=temp.load(),
                                   target=node.target,
                                   body=body,
                                   else_body=else_body)

        #--------------------------------------------------------------------
        # Patch the body and else clause
        #--------------------------------------------------------------------

        body.body.extend(node.body)
        else_body.body.extend(node.orelse)

        while_node = result.body[-1]
        assert isinstance(while_node, ast.While)

        target_increment = while_node.body[-1]
        assert isinstance(target_increment, ast.Assign)

        # Add target variable increment basic block
        node.incr_block.body = [target_increment]
        while_node.body[-1] = node.incr_block

        #--------------------------------------------------------------------
        # Create a While with the ForNode's cfg blocks merged in
        #--------------------------------------------------------------------

        while_node = make_while_loop(while_node)
        copy_basic_blocks(node, while_node)
        while_node = nodes.build_while(**vars(while_node))

        # Create the place to jump to for 'continue'
        while_node.continue_block = node.incr_block

        # Set the new while loop in the templated Suite
        result.body[-1] = while_node

        return result
示例#12
0
    def visit_For(self, node):
        if node.orelse:
            raise error.NumbaError(node, 'Else in for-loop is not implemented.')

        if node.iter.type.is_range:
            self.generic_visit(node)

            temp = nodes.TempNode(node.target.type)
            nsteps = nodes.TempNode(Py_ssize_t)
            start, stop, step = unpack_range_args(node.iter)

            if isinstance(step, nodes.ConstNode):
                have_step = step.pyval != 1
            else:
                have_step = True

            start, stop, step = [nodes.CloneableNode(n)
                                     for n in (start, stop, step)]

            if have_step:
                s1 = self.run_template(
                        """
                            $length = {{stop}} - {{start}}
                            {{nsteps}} = $length / {{step}}
                            if $length % {{step}}:
                                {{nsteps}} = {{nsteps_load}} + 1
                        """,
                        vars=dict(length=Py_ssize_t),
                        start=start, stop=stop, step=step,
                        nsteps=nsteps.store(), nsteps_load=nsteps.load())
                step = step.clone
            else:
                s1 = self.run_template(
                    "{{nsteps}} = {{stop}} - {{start}}",
                    start=start, stop=stop, nsteps=nsteps.store())

            # Rely on LLVM strength reduction. It's easier this way, or we
            # need to make the assignment to 'target' conditional for zero
            # iterations
            s2 = self.run_template(
                    "{{target}} = {{start}} + {{temp}} * {{step}}",
                    target=node.target, start=start.clone, stop=stop.clone,
                    step=step, temp=temp.load())

            body = node.body
            body.insert(0, s2)
            zero = nodes.const(0, nsteps.type)
            one = nodes.const(1, nsteps.type)
            return ast.Suite([s1, nodes.ForRangeNode(index=temp.load(),
                                                     target=temp.store(),
                                                     start=zero,
                                                     stop=nsteps.load(),
                                                     step=one,
                                                     body=body)])
        elif node.iter.type.is_array and node.iter.type.ndim == 1:
            # Convert 1D array iteration to for-range and indexing
            logger.debug(ast.dump(node))

            orig_target = node.target
            orig_iter = node.iter

            # replace node.target with a temporary
            target_name = orig_target.id + '.idx'
            target_temp = nodes.TempNode(Py_ssize_t)
            node.target = target_temp.store()

            # replace node.iter
            call_func = ast.Name(id='range', ctx=ast.Load())
            call_func.type = numba_types.RangeType()
            call_func.variable = Variable(call_func.type)

            shape_index = ast.Index(nodes.ConstNode(0, numba_types.Py_ssize_t))
            shape_index.type = numba_types.npy_intp
            stop = ast.Subscript(value=nodes.ShapeAttributeNode(orig_iter),
                                 slice=shape_index,
                                 ctx=ast.Load())
            stop.type = numba_types.intp
            stop.variable = Variable(stop.type)
            call_args = [nodes.ConstNode(0, numba_types.Py_ssize_t),
                         nodes.CoercionNode(stop, numba_types.Py_ssize_t),
                         nodes.ConstNode(1, numba_types.Py_ssize_t),]

            node.iter = ast.Call(func=call_func, args=call_args)
            node.iter.type = call_func.type

            node.index = target_temp.load()
            # add assignment to new target variable at the start of the body
            index = ast.Index(value=node.index)
            index.type = target_temp.type
            subscript = ast.Subscript(value=orig_iter,
                                      slice=index, ctx=ast.Load())
            subscript.type = orig_iter.variable.type.dtype
            subscript.variable = Variable(subscript.type)
            coercion = nodes.CoercionNode(subscript, orig_target.type)
            assign = ast.Assign(targets=[orig_target], value=subscript)

            node.body = [assign] + node.body

            return self.visit(node)
        else:
            raise error.NumbaError("Unsupported for loop pattern")
示例#13
0
    def rewrite_range_iteration(self, node):
        """
        Handle range iteration:

            for i in range(start, stop, step):
                ...

        becomes

            nsteps = compute_nsteps(start, stop, step)
            temp = 0

            while temp < nsteps:
                target = start + temp * step
                ...
                temp += 1
        """
        self.generic_visit(node)

        temp = nodes.TempNode(node.target.type, 'target_temp')
        nsteps = nodes.TempNode(Py_ssize_t, 'nsteps')
        start, stop, step = unpack_range_args(node.iter)

        if isinstance(step, nodes.ConstNode):
            have_step = step.pyval != 1
        else:
            have_step = True

        start, stop, step = map(nodes.CloneableNode, (start, stop, step))

        if have_step:
            templ = textwrap.dedent("""
                    {{temp}} = 0
                    {{nsteps}} = ({{stop}} - {{start}} + {{step}} -
                                    (1 if {{step}} >= 0 else -1)) / {{step}}
                    while {{temp_load}} < {{nsteps_load}}:
                        {{target}} = {{start}} + {{temp_load}} * {{step}}
                        {{temp}} = {{temp_load}} + 1
                        {{body}}
                """)
        else:
            templ = textwrap.dedent("""
                    {{temp}} = {{start}}
                    {{nsteps}} = {{stop}}
                    while {{temp_load}} < {{nsteps_load}}:
                        {{target}} = {{temp_load}}
                        {{temp}} = {{temp_load}} + 1
                        {{body}}
                """)

        if node.orelse:
            templ += "\nelse: {{else_body}}"

        # Leave the bodies empty, they are already analyzed
        body = ast.Suite(body=[])
        else_body = ast.Suite(body=[])

        #--------------------------------------------------------------------
        # Substitute template and infer types
        #--------------------------------------------------------------------

        result = self.run_template(templ,
                                   vars=dict(length=Py_ssize_t),
                                   start=start,
                                   stop=stop,
                                   step=step,
                                   nsteps=nsteps.store(),
                                   nsteps_load=nsteps.load(),
                                   temp=temp.store(),
                                   temp_load=temp.load(),
                                   target=node.target,
                                   body=body,
                                   else_body=else_body)
        ast.copy_location(result, node)
        if hasattr(node, 'lineno'):
            visitor = missing.FixMissingLocations(node.lineno,
                                                  node.col_offset,
                                                  override=True)
            visitor.visit(result)

        #--------------------------------------------------------------------
        # Patch the body and else clause
        #--------------------------------------------------------------------

        body.body.extend(node.body)
        else_body.body.extend(node.orelse)

        while_node = result.body[-1]
        assert isinstance(while_node, ast.While)

        #--------------------------------------------------------------------
        # Create a While with the ForNode's cfg blocks merged in
        #--------------------------------------------------------------------

        while_node = make_while_loop(while_node)
        copy_basic_blocks(node, while_node)
        while_node = nodes.build_while(**vars(while_node))

        # Create the place to jump to for 'continue'
        while_node.continue_block = node.cond_block

        # Set the new while loop in the templated Suite
        result.body[-1] = while_node

        return result
示例#14
0
    def test_empty_init(self):
        # Jython 2.5.0 did not allow empty constructors for many ast node types
        # but CPython ast nodes do allow this.  For the moment, I don't see a
        # reason to allow construction of the super types (like ast.AST and
        # ast.stmt) as well as the op types that are implemented as enums in
        # Jython (like boolop), but I've left them in but commented out for
        # now.  We may need them in the future since CPython allows this, but
        # it may fall under implementation detail.

        #ast.AST()
        ast.Add()
        ast.And()
        ast.Assert()
        ast.Assign()
        ast.Attribute()
        ast.AugAssign()
        ast.AugLoad()
        ast.AugStore()
        ast.BinOp()
        ast.BitAnd()
        ast.BitOr()
        ast.BitXor()
        ast.BoolOp()
        ast.Break()
        ast.Call()
        ast.ClassDef()
        ast.Compare()
        ast.Continue()
        ast.Del()
        ast.Delete()
        ast.Dict()
        ast.Div()
        ast.Ellipsis()
        ast.Eq()
        ast.Exec()
        ast.Expr()
        ast.Expression()
        ast.ExtSlice()
        ast.FloorDiv()
        ast.For()
        ast.FunctionDef()
        ast.GeneratorExp()
        ast.Global()
        ast.Gt()
        ast.GtE()
        ast.If()
        ast.IfExp()
        ast.Import()
        ast.ImportFrom()
        ast.In()
        ast.Index()
        ast.Interactive()
        ast.Invert()
        ast.Is()
        ast.IsNot()
        ast.LShift()
        ast.Lambda()
        ast.List()
        ast.ListComp()
        ast.Load()
        ast.Lt()
        ast.LtE()
        ast.Mod()
        ast.Module()
        ast.Mult()
        ast.Name()
        ast.Not()
        ast.NotEq()
        ast.NotIn()
        ast.Num()
        ast.Or()
        ast.Param()
        ast.Pass()
        ast.Pow()
        ast.Print()
        ast.RShift()
        ast.Raise()
        ast.Repr()
        ast.Return()
        ast.Slice()
        ast.Store()
        ast.Str()
        ast.Sub()
        ast.Subscript()
        ast.Suite()
        ast.TryExcept()
        ast.TryFinally()
        ast.Tuple()
        ast.UAdd()
        ast.USub()
        ast.UnaryOp()
        ast.While()
        ast.With()
        ast.Yield()
        ast.alias()
        ast.arguments()
        #ast.boolop()
        #ast.cmpop()
        ast.comprehension()
        #ast.excepthandler()
        #ast.expr()
        #ast.expr_context()
        ast.keyword()
示例#15
0
    def register_array_expression(self, node, lhs=None):
        super(ArrayExpressionRewriteNative, self).register_array_expression(
            node, lhs)

        lhs_type = lhs.type if lhs else node.type
        is_expr = lhs is None

        if node.type.is_array and lhs_type.ndim < node.type.ndim:
            # TODO: this is valid in NumPy if the leading dimensions of the
            # TODO: RHS have extent 1
            raise error.NumbaError(
                node, "Right hand side must have a "
                      "dimensionality <= %d" % lhs_type.ndim)

        # Create ufunc scalar kernel
        ufunc_ast, signature, ufunc_builder = self.get_py_ufunc_ast(lhs, node)
        signature.struct_by_reference = True

        # Compile ufunc scalar kernel with numba
        ast.fix_missing_locations(ufunc_ast)
        func_env, (_, _, _) = pipeline.run_pipeline2(
            self.env, None, ufunc_ast, signature,
            function_globals={},
        )

        # Manual linking
        lfunc = func_env.lfunc

        # print lfunc
        operands = ufunc_builder.operands
        functions.keep_alive(self.func, lfunc)

        operands = [nodes.CloneableNode(operand) for operand in operands]

        if lhs is not None:
            lhs = nodes.CloneableNode(lhs)
            broadcast_operands = [lhs] + operands
            lhs = lhs.clone
        else:
            broadcast_operands = operands[:]

        shape = slicenodes.BroadcastNode(lhs_type, broadcast_operands)
        operands = [op.clone for op in operands]

        if lhs is None and self.nopython:
            raise error.NumbaError(
                node, "Cannot allocate new memory in nopython context")
        elif lhs is None:
            # TODO: determine best output order at runtime
            shape = shape.cloneable
            lhs = nodes.ArrayNewEmptyNode(lhs_type, shape.clone,
                                          lhs_type.is_f_contig).cloneable

        # Build minivect wrapper kernel
        context = NumbaproStaticArgsContext()
        context.llvm_module = self.env.llvm_context.module
        # context.debug = True
        context.optimize_broadcasting = False
        b = context.astbuilder

        variables = [b.variable(name_node.type, "op%d" % i)
                     for i, name_node in enumerate([lhs] + operands)]
        miniargs = [b.funcarg(variable) for variable in variables]
        body = miniutils.build_kernel_call(lfunc.name, signature, miniargs, b)

        minikernel = b.function_from_numpy(
            templating.temp_name("array_expression"), body, miniargs)
        lminikernel, ctypes_kernel = context.run_simple(
            minikernel, specializers.StridedSpecializer)

        # Build call to minivect kernel
        operands.insert(0, lhs)
        args = [shape]
        scalar_args = []
        for operand in operands:
            if operand.type.is_array:
                data_p = self.array_attr(operand, 'data')
                data_p = nodes.CoercionNode(data_p,
                                            operand.type.dtype.pointer())
                if not isinstance(operand, nodes.CloneNode):
                    operand = nodes.CloneNode(operand)
                strides_p = self.array_attr(operand, 'strides')
                args.extend((data_p, strides_p))
            else:
                scalar_args.append(operand)

        args.extend(scalar_args)
        result = nodes.NativeCallNode(minikernel.type, args, lminikernel)

        # Use native slicing in array expressions
        slicenodes.mark_nopython(ast.Suite(body=result.args))

        if not is_expr:
            # a[:] = b[:] * c[:]
            return result

        # b[:] * c[:], return new array as expression
        return nodes.ExpressionNode(stmts=[result], expr=lhs.clone)