Ejemplo n.º 1
0
    def run(self):
        dprint_func_ir(self.func_ir, "starting hiframes")
        topo_order = find_topo_order(self.func_ir.blocks)
        for label in topo_order:
            self._get_reverse_copies(self.func_ir.blocks[label].body)
            new_body = []
            for inst in self.func_ir.blocks[label].body:
                # df['col'] = arr
                if isinstance(
                        inst,
                        ir.StaticSetItem) and inst.target.name in self.df_vars:
                    df_name = inst.target.name
                    self.df_vars[df_name][inst.index] = inst.value
                    self._update_df_cols()
                elif isinstance(inst, ir.Assign):
                    out_nodes = self._run_assign(inst)
                    if isinstance(out_nodes, list):
                        new_body.extend(out_nodes)
                    if isinstance(out_nodes, dict):
                        label = include_new_blocks(self.func_ir.blocks,
                                                   out_nodes, label, new_body)
                        new_body = []
                else:
                    new_body.append(inst)
            self.func_ir.blocks[label].body = new_body

        self.func_ir._definitions = get_definitions(self.func_ir.blocks)
        self.func_ir.df_cols = self.df_cols
        #remove_dead(self.func_ir.blocks, self.func_ir.arg_names)
        dprint_func_ir(self.func_ir, "after hiframes")
        if numba.config.DEBUG_ARRAY_OPT == 1:
            print("df_vars: ", self.df_vars)
        return
Ejemplo n.º 2
0
def get_stencil_accesses(parfor, typemap):
    # if a parfor has stencil pattern, see which accesses depend on loop index
    # XXX: assuming loop index is not used for non-stencil arrays
    # TODO support recursive parfor, multi-D, mutiple body blocks

    # no access if not stencil
    is_stencil = False
    for pattern in parfor.patterns:
        if pattern[0] == 'stencil':
            is_stencil = True
            neighborhood = pattern[1]
    if not is_stencil:
        return {}, None

    par_index_var = parfor.loop_nests[0].index_variable
    body = parfor.loop_body
    body_defs = get_definitions(body)

    stencil_accesses = {}

    for block in body.values():
        for stmt in block.body:
            if isinstance(stmt, ir.Assign) and isinstance(stmt.value, ir.Expr):
                lhs = stmt.target.name
                rhs = stmt.value
                if (rhs.op == 'getitem' and is_array(rhs.value.name, typemap)
                        and vars_dependent(body_defs, rhs.index,
                                           par_index_var)):
                    stencil_accesses[rhs.index.name] = rhs.value.name

    return stencil_accesses, neighborhood
Ejemplo n.º 3
0
    def run(self):
        blocks = self.func_ir.blocks
        call_table, _ = ir_utils.get_call_table(blocks)
        topo_order = find_topo_order(blocks)
        for label in topo_order:
            new_body = []
            for inst in blocks[label].body:
                if isinstance(inst, ir.Assign):
                    out_nodes = self._run_assign(inst, call_table)
                    if isinstance(out_nodes, list):
                        new_body.extend(out_nodes)
                    if isinstance(out_nodes, dict):
                        label = include_new_blocks(blocks, out_nodes, label,
                                                   new_body)
                        new_body = []
                    if isinstance(out_nodes, tuple):
                        gen_blocks, post_nodes = out_nodes
                        label = include_new_blocks(blocks, gen_blocks, label,
                                                   new_body)
                        new_body = post_nodes
                else:
                    new_body.append(inst)
            blocks[label].body = new_body

        self.func_ir._definitions = get_definitions(self.func_ir.blocks)
        return
Ejemplo n.º 4
0
 def run(self):
     dprint_func_ir(self.func_ir, "starting IO")
     topo_order = find_topo_order(self.func_ir.blocks)
     for label in topo_order:
         new_body = []
         # copies are collected before running the pass since
         # variables typed in locals are assigned late
         self._get_reverse_copies(self.func_ir.blocks[label].body)
         for inst in self.func_ir.blocks[label].body:
             if isinstance(inst, ir.Assign):
                 inst_list = self._run_assign(inst)
                 new_body.extend(inst_list)
             elif isinstance(inst, ir.StaticSetItem):
                 inst_list = self._run_static_setitem(inst)
                 new_body.extend(inst_list)
             else:
                 new_body.append(inst)
         self.func_ir.blocks[label].body = new_body
     # iterative remove dead to make sure all extra code (e.g. df vars) is removed
     while remove_dead(self.func_ir.blocks, self.func_ir.arg_names,
                       self.func_ir):
         pass
     self.func_ir._definitions = get_definitions(self.func_ir.blocks)
     dprint_func_ir(self.func_ir, "after IO")
     if debug_prints():
         print("h5 files: ", self.h5_files)
         print("h5 dsets: ", self.h5_dsets)
Ejemplo n.º 5
0
    def run(self):
        dprint_func_ir(self.func_ir, "starting hiframes")
        topo_order = find_topo_order(self.func_ir.blocks)
        for label in topo_order:
            new_body = []
            for inst in self.func_ir.blocks[label].body:
                # df['col'] = arr
                if isinstance(inst, ir.StaticSetItem) and inst.target.name in self.df_vars:
                    df_name = inst.target.name
                    self.df_vars[df_name][inst.index] = inst.value
                    self._update_df_cols()
                elif isinstance(inst, ir.Assign):
                    out_nodes = self._run_assign(inst)
                    if isinstance(out_nodes, list):
                        new_body.extend(out_nodes)
                    if isinstance(out_nodes, dict):
                        label = include_new_blocks(self.func_ir.blocks, out_nodes, label, new_body)
                        new_body = []
                else:
                    new_body.append(inst)
            self.func_ir.blocks[label].body = new_body

        self.func_ir._definitions = get_definitions(self.func_ir.blocks)
        #remove_dead(self.func_ir.blocks, self.func_ir.arg_names)
        if config._has_h5py:
            io_pass = pio.PIO(self.func_ir, self.locals)
            io_pass.run()
        remove_dead(self.func_ir.blocks, self.func_ir.arg_names)
        DummyFlags = namedtuple('DummyFlags', 'auto_parallel')
        inline_pass = InlineClosureCallPass(self.func_ir, DummyFlags(True))
        inline_pass.run()
        self.typemap, self.return_type, self.calltypes = numba_compiler.type_inference_stage(
                self.typingctx, self.func_ir, self.args, None)
        self.fixes_after_typing(self.func_ir.blocks)
        self.func_ir._definitions = get_definitions(self.func_ir.blocks)
        dprint_func_ir(self.func_ir, "after hiframes")
        if numba.config.DEBUG_ARRAY_OPT==1:
            print("df_vars: ", self.df_vars)
        return
Ejemplo n.º 6
0
def inline_calls(func_ir):
    call_table, _ = ir_utils.get_call_table(func_ir.blocks)
    for label, block in func_ir.blocks.items():
        for i, stmt in enumerate(block.body):
            if isinstance(stmt, ir.Assign):
                rhs = stmt.value
                if isinstance(rhs, ir.Expr) and rhs.op == 'call':
                    func = rhs.func.name
                    if (func in call_table and call_table[func] and isinstance(
                            call_table[func][0], CPUDispatcher)):
                        py_func = call_table[func][0].py_func
                        inline_calls_inner(func_ir, block, stmt, i, py_func)
                        return  # inline_calls_inner will call back recursively
    func_ir._definitions = get_definitions(func_ir.blocks)
Ejemplo n.º 7
0
 def run(self):
     dprint_func_ir(self.func_ir, "starting IO")
     topo_order = find_topo_order(self.func_ir.blocks)
     for label in topo_order:
         new_body = []
         # copies are collected before running the pass since
         # variables typed in locals are assigned late
         self._get_reverse_copies(self.func_ir.blocks[label].body)
         for inst in self.func_ir.blocks[label].body:
             if isinstance(inst, ir.Assign):
                 inst_list = self._run_assign(inst)
                 new_body.extend(inst_list)
             elif isinstance(inst, ir.StaticSetItem):
                 inst_list = self._run_static_setitem(inst)
                 new_body.extend(inst_list)
             else:
                 new_body.append(inst)
         self.func_ir.blocks[label].body = new_body
     remove_dead(self.func_ir.blocks, self.func_ir.arg_names)
     self.func_ir._definitions = get_definitions(self.func_ir.blocks)
     dprint_func_ir(self.func_ir, "after IO")
     if config.DEBUG_ARRAY_OPT == 1:
         print("h5 files: ", self.h5_files)
         print("h5 dsets: ", self.h5_dsets)
Ejemplo n.º 8
0
    def run(self):
        blocks = self.func_ir.blocks
        topo_order = find_topo_order(blocks)
        for label in topo_order:
            new_body = []
            for inst in blocks[label].body:
                if isinstance(inst, ir.Assign):
                    out_nodes = self._run_assign(inst)
                    if isinstance(out_nodes, list):
                        new_body.extend(out_nodes)
                    if isinstance(out_nodes, dict):
                        label = include_new_blocks(blocks, out_nodes, label,
                                                   new_body)
                        new_body = []
                    if isinstance(out_nodes, tuple):
                        gen_blocks, post_nodes = out_nodes
                        label = include_new_blocks(blocks, gen_blocks, label,
                                                   new_body)
                        new_body = post_nodes
                else:
                    new_body.append(inst)
            blocks[label].body = new_body

        if debug_prints():  # pragma: no cover
            print("--- types before Series replacement:", self.typemap)
            print("calltypes: ", self.calltypes)

        replace_series = {}
        for vname, typ in self.typemap.items():
            if isinstance(typ, SeriesType):
                # print("replacing series type", vname)
                new_typ = series_to_array_type(typ)
                replace_series[vname] = new_typ
            # replace array.call() variable types
            if isinstance(typ, types.BoundFunction) and isinstance(
                    typ.this, SeriesType):
                this = series_to_array_type(typ.this)
                # TODO: handle string arrays, etc.
                assert typ.typing_key.startswith('array.')
                attr = typ.typing_key[len('array.'):]
                resolver = getattr(ArrayAttribute, 'resolve_' + attr)
                # methods are either installed with install_array_method or
                # using @bound_function in arraydecl.py
                if hasattr(resolver, '__wrapped__'):
                    resolver = bound_function(typ.typing_key)(
                        resolver.__wrapped__)
                new_typ = resolver(ArrayAttribute(self.typingctx), this)
                replace_series[vname] = new_typ

        for vname, typ in replace_series.items():
            self.typemap.pop(vname)
            self.typemap[vname] = typ

        replace_calltype = {}
        # replace sig of getitem/setitem/... series type with array
        for call, sig in self.calltypes.items():
            if sig is None:
                continue
            assert isinstance(sig, Signature)
            sig.return_type = if_series_to_array_type(sig.return_type)
            sig.args = tuple(map(if_series_to_array_type, sig.args))
            # XXX: side effect: force update of call signatures
            if isinstance(call, ir.Expr) and call.op == 'call':
                # StencilFunc requires kws for typing so sig.args can't be used
                # reusing sig.args since some types become Const in sig
                argtyps = sig.args[:len(call.args)]
                kwtyps = {name: self.typemap[v.name] for name, v in call.kws}

                new_sig = self.typemap[call.func.name].get_call_type(
                    self.typingctx, argtyps, kwtyps)
                # calltypes of things like BoundFunction (array.call) need to
                # be update for lowering to work
                # XXX: new_sig could be None for things like np.int32()
                if call in self.calltypes and new_sig is not None:
                    old_sig = self.calltypes[call]
                    # fix types with undefined dtypes in empty_inferred, etc.
                    return_type = _fix_typ_undefs(new_sig.return_type,
                                                  old_sig.return_type)
                    args = tuple(
                        _fix_typ_undefs(a, b)
                        for a, b in zip(new_sig.args, old_sig.args))
                    replace_calltype[call] = Signature(return_type, args,
                                                       new_sig.recvr,
                                                       new_sig.pysig)

        for call, sig in replace_calltype.items():
            self.calltypes.pop(call)
            self.calltypes[call] = sig

        if debug_prints():  # pragma: no cover
            print("--- types after Series replacement:", self.typemap)
            print("calltypes: ", self.calltypes)

        self.func_ir._definitions = get_definitions(self.func_ir.blocks)
        return if_series_to_unbox(self.return_type)