# Buggy code
def run(self):
    """run parfor conversion pass: replace Numpy calls
    with Parfors when possible and optimize the IR."""
    # run array analysis, a pre-requisite for parfor translation
    remove_dels(self.func_ir.blocks)
    self.array_analysis.run(self.func_ir.blocks)
    # run stencil translation to parfor
    if self.options.stencil:
        stencil_pass = StencilPass(
            self.func_ir,
            self.typemap,
            self.calltypes,
            self.array_analysis,
            self.typingctx,
            self.flags,
        )
        stencil_pass.run()
    if self.options.setitem:
        self._convert_setitem(self.func_ir.blocks)
    if self.options.numpy:
        self._convert_numpy(self.func_ir.blocks)
    if self.options.reduction:
        self._convert_reduce(self.func_ir.blocks)
    if self.options.prange:
        self._convert_loop(self.func_ir.blocks)

    # setup diagnostics now parfors are found
    self.diagnostics.setup(self.func_ir, self.options.fusion)

    dprint_func_ir(self.func_ir, "after parfor pass")

    # simplify CFG of parfor body loops since nested parfors with extra
    # jumps can be created with prange conversion
    simplify_parfor_body_CFG(self.func_ir.blocks)
    # simplify before fusion
    simplify(self.func_ir, self.typemap, self.calltypes)
    # need two rounds of copy propagation to enable fusion of long sequences
    # of parfors like test_fuse_argmin (some PYTHONHASHSEED values since
    # apply_copies_parfor depends on set order for creating dummy assigns)
    simplify(self.func_ir, self.typemap, self.calltypes)

    if self.options.fusion:
        self.func_ir._definitions = build_definitions(self.func_ir.blocks)
        self.array_analysis.equiv_sets = dict()
        self.array_analysis.run(self.func_ir.blocks)
        # reorder statements to maximize fusion
        # push non-parfors down
        maximize_fusion(
            self.func_ir, self.func_ir.blocks, self.typemap, up_direction=False
        )
        dprint_func_ir(self.func_ir, "after maximize fusion down")
        self.fuse_parfors(self.array_analysis, self.func_ir.blocks)
        # push non-parfors up
        maximize_fusion(self.func_ir, self.func_ir.blocks, self.typemap)
        dprint_func_ir(self.func_ir, "after maximize fusion up")
        # try fuse again after maximize
        self.fuse_parfors(self.array_analysis, self.func_ir.blocks)
        dprint_func_ir(self.func_ir, "after fusion")
    # simplify again
    simplify(self.func_ir, self.typemap, self.calltypes)
    # push function call variables inside parfors so gufunc function
    # wouldn't need function variables as argument
    push_call_vars(self.func_ir.blocks, {}, {})
    # simplify again
    simplify(self.func_ir, self.typemap, self.calltypes)
    dprint_func_ir(self.func_ir, "after optimization")
    if config.DEBUG_ARRAY_OPT >= 1:
        print("variable types: ", sorted(self.typemap.items()))
        print("call types: ", self.calltypes)
    # run post processor again to generate Del nodes
    post_proc = postproc.PostProcessor(self.func_ir)
    post_proc.run()
    if self.func_ir.is_generator:
        fix_generator_types(self.func_ir.generator_info, self.return_type, self.typemap)
    if sequential_parfor_lowering:
        lower_parfor_sequential(
            self.typingctx, self.func_ir, self.typemap, self.calltypes
        )
    else:
        # prepare for parallel lowering
        # add parfor params to parfors here since lowering is destructive
        # changing the IR after this is not allowed
        parfor_ids = get_parfor_params(
            self.func_ir.blocks, self.options.fusion, self.nested_fusion_info
        )
        if config.DEBUG_ARRAY_OPT_STATS:
            name = self.func_ir.func_id.func_qualname
            n_parfors = len(parfor_ids)
            if n_parfors > 0:
                after_fusion = (
                    "After fusion" if self.options.fusion else "With fusion disabled"
                )
                print(
                    ("{}, function {} has {} parallel for-loop(s) #{}.").format(
                        after_fusion, name, n_parfors, parfor_ids
                    )
                )
            else:
                print("Function {} has no Parfor.".format(name))

    return


# Traceback (AssertionError)
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/errors.py in new_error_context(fmt_, *args, **kwargs)
661     try:
--> 662         yield
663     except NumbaError as e:

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/lowering.py in lower_block(self, block)
257                                    loc=self.loc, errcls_=defaulterrcls):
--> 258                 self.lower_inst(inst)
259

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/lowering.py in lower_inst(self, inst)
409                 if isinstance(inst, _class):
--> 410                     func(self, inst)
411                     return

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/npyufunc/parfor.py in _lower_parfor_parallel(lowerer, parfor)
97     parfor_redvars, parfor_reddict = numba.parfor.get_parfor_reductions(
---> 98         parfor, parfor.params, lowerer.fndesc.calltypes)
99

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/parfor.py in get_parfor_reductions(parfor, parfor_params, calltypes, reductions, reduce_varnames, param_uses, param_nodes, var_to_param)
2968             param_nodes[param].reverse()
-> 2969             reduce_nodes = get_reduce_nodes(param, param_nodes[param])
2970             init_val = guard(get_reduction_init, reduce_nodes)

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/parfor.py in get_reduce_nodes(name, nodes)
3017                 non_red_args = [ x for (x, y) in args if y.name != name ]
-> 3018                 assert len(non_red_args) == 1
3019                 args = [ (x, y) for (x, y) in args if x != y.name ]

AssertionError:

During handling of the above exception, another exception occurred:

LoweringError                             Traceback (most recent call last)
<ipython-input-79-3ff90f149e7e> in <module>
1 n_sims = 100
----> 2 level_data_simulations = run_simulations(n_players, n_sims, t_levels, t_player, player, max_level)

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/dispatcher.py in _compile_for_args(self, *args, **kws)
393                     e.patch_message(''.join(e.args) + help_msg)
394             # ignore the FULL_TRACEBACKS config, this needs reporting!
--> 395             raise e
396
397     def inspect_llvm(self, signature=None):

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/dispatcher.py in _compile_for_args(self, *args, **kws)
350                 argtypes.append(self.typeof_pyval(a))
351         try:
--> 352             return self.compile(tuple(argtypes))
353         except errors.TypingError as e:
354             # Intercept typing error that may be due to an argument

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler_lock.py in _acquire_compile_lock(*args, **kwargs)
30         def _acquire_compile_lock(*args, **kwargs):
31             with self:
---> 32                 return func(*args, **kwargs)
33         return _acquire_compile_lock
34

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/dispatcher.py in compile(self, sig)
691
692             self._cache_misses[sig] += 1
--> 693             cres = self._compiler.compile(args, return_type)
694             self.add_overload(cres)
695             self._cache.save_overload(sig, cres)

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/dispatcher.py in compile(self, args, return_type)
74
75     def compile(self, args, return_type):
---> 76         status, retval = self._compile_cached(args, return_type)
77         if status:
78             return retval

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/dispatcher.py in _compile_cached(self, args, return_type)
88
89         try:
---> 90             retval = self._compile_core(args, return_type)
91         except errors.TypingError as e:
92             self._failed_cache[key] = e

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/dispatcher.py in _compile_core(self, args, return_type)
106                                       args=args, return_type=return_type,
107                                       flags=flags, locals=self.locals,
--> 108                                       pipeline_class=self.pipeline_class)
109         # Check typing error if object mode is used
110         if cres.typing_error is not None and not flags.enable_pyobject:

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py in compile_extra(typingctx, targetctx, func, args, return_type, flags, locals, library, pipeline_class)
970     pipeline = pipeline_class(typingctx, targetctx, library,
971                               args, return_type, flags, locals)
--> 972     return pipeline.compile_extra(func)
973
974

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py in compile_extra(self, func)
388         self.lifted = ()
389         self.lifted_from = None
--> 390         return self._compile_bytecode()
391
392     def compile_ir(self, func_ir, lifted=(), lifted_from=None):

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py in _compile_bytecode(self)
901         """
902         assert self.func_ir is None
--> 903         return self._compile_core()
904
905     def _compile_ir(self):

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py in _compile_core(self)
888         self.define_pipelines(pm)
889         pm.finalize()
--> 890         res = pm.run(self.status)
891         if res is not None:
892             # Early pipeline completion

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler_lock.py in _acquire_compile_lock(*args, **kwargs)
30         def _acquire_compile_lock(*args, **kwargs):
31             with self:
---> 32                 return func(*args, **kwargs)
33         return _acquire_compile_lock
34

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py in run(self, status)
264                     # No more fallback pipelines?
265                     if is_final_pipeline:
--> 266                         raise patched_exception
267                     # Go to next fallback pipeline
268                     else:

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py in run(self, status)
255                 try:
256                     event("-- %s" % stage_name)
--> 257                     stage()
258                 except _EarlyPipelineCompletion as e:
259                     return e.result

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py in stage_nopython_backend(self)
762         """
763         lowerfn = self.backend_nopython_mode
--> 764         self._backend(lowerfn, objectmode=False)
765
766     def stage_compile_interp_mode(self):

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py in _backend(self, lowerfn, objectmode)
701             self.library.enable_object_caching()
702
--> 703         lowered = lowerfn()
704         signature = typing.signature(self.return_type, *self.args)
705         self.cr = compile_result(

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py in backend_nopython_mode(self)
688                 self.calltypes,
689                 self.flags,
--> 690                 self.metadata)
691
692     def _backend(self, lowerfn, objectmode):

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py in native_lowering_stage(targetctx, library, interp, typemap, restype, calltypes, flags, metadata)
1141         lower = lowering.Lower(targetctx, library, fndesc, interp,
1142                                metadata=metadata)
-> 1143         lower.lower()
1144         if not flags.no_cpython_wrapper:
1145             lower.create_cpython_wrapper(flags.release_gil)

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/lowering.py in lower(self)
175         if self.generator_info is None:
176             self.genlower = None
--> 177             self.lower_normal_function(self.fndesc)
178         else:
179             self.genlower = self.GeneratorLower(self)

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/lowering.py in lower_normal_function(self, fndesc)
216         # Init argument values
217         self.extract_function_arguments()
--> 218         entry_block_tail = self.lower_function_body()
219
220         # Close tail of entry block

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/lowering.py in lower_function_body(self)
241             bb = self.blkmap[offset]
242             self.builder.position_at_end(bb)
--> 243             self.lower_block(block)
244
245         self.post_lower()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/lowering.py in lower_block(self, block)
256             with new_error_context('lowering "{inst}" at {loc}', inst=inst,
257                                    loc=self.loc, errcls_=defaulterrcls):
--> 258                 self.lower_inst(inst)
259
260     def create_cpython_wrapper(self, release_gil=False):

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/contextlib.py in __exit__(self, type, value, traceback)
128                 value = type()
129             try:
--> 130                 self.gen.throw(type, value, traceback)
131             except StopIteration as exc:
132                 # Suppress StopIteration *unless* it's the same exception that

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/errors.py in new_error_context(fmt_, *args, **kwargs)
668         from numba import config
669         tb = sys.exc_info()[2] if config.FULL_TRACEBACKS else None
--> 670         six.reraise(type(newerr), newerr, tb)
671
672

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/six.py in reraise(tp, value, tb)
657         if value.__traceback__ is not tb:
658             raise value.with_traceback(tb)
--> 659         raise value
660
661 else:

LoweringError: Failed in nopython mode pipeline (step: nopython mode backend)


File "<ipython-input-78-9c8bcba8955a>", line 4:
def run_simulations(n_p, n_s, t_lvl, t_plr, plr,mx_lvl):
<source elided>
#    lvl_sims = np.empty(shape=(np.shape(lvl)[0], np.shape(lvl)[1], n_s))
for s in prange(n_s):
^

[1] During: lowering "id=0[LoopNest(index_variable = parfor_index.10, range = (0, n_s, 1))]{12: <ir.Block at <ipython-input-78-9c8bcba8955a> (4)>}Var(parfor_index.10, <ipython-input-78-9c8bcba8955a> (4))" at <ipython-input-78-9c8bcba8955a> (4)
-------------------------------------------------------------------------------
This should not have happened, a problem has occurred in Numba's internals.
You are currently using Numba version 0.45.1.

Please report the error message and traceback, along with a minimal reproducer
at: https://github.com/numba/numba/issues/new

If more help is needed please feel free to speak to the Numba core developers
directly at: https://gitter.im/numba/numba

Thanks in advance for your help in improving Numba!

# Fixed code
def run(self):
    """run parfor conversion pass: replace Numpy calls
    with Parfors when possible and optimize the IR."""
    # run array analysis, a pre-requisite for parfor translation
    remove_dels(self.func_ir.blocks)
    self.array_analysis.run(self.func_ir.blocks)
    # run stencil translation to parfor
    if self.options.stencil:
        stencil_pass = StencilPass(
            self.func_ir,
            self.typemap,
            self.calltypes,
            self.array_analysis,
            self.typingctx,
            self.flags,
        )
        stencil_pass.run()
    if self.options.setitem:
        self._convert_setitem(self.func_ir.blocks)
    if self.options.numpy:
        self._convert_numpy(self.func_ir.blocks)
    if self.options.reduction:
        self._convert_reduce(self.func_ir.blocks)
    if self.options.prange:
        self._convert_loop(self.func_ir.blocks)

    # setup diagnostics now parfors are found
    self.diagnostics.setup(self.func_ir, self.options.fusion)

    dprint_func_ir(self.func_ir, "after parfor pass")

    # simplify CFG of parfor body loops since nested parfors with extra
    # jumps can be created with prange conversion
    simplify_parfor_body_CFG(self.func_ir.blocks)
    # simplify before fusion
    simplify(self.func_ir, self.typemap, self.calltypes)
    # need two rounds of copy propagation to enable fusion of long sequences
    # of parfors like test_fuse_argmin (some PYTHONHASHSEED values since
    # apply_copies_parfor depends on set order for creating dummy assigns)
    simplify(self.func_ir, self.typemap, self.calltypes)

    if self.options.fusion:
        self.func_ir._definitions = build_definitions(self.func_ir.blocks)
        self.array_analysis.equiv_sets = dict()
        self.array_analysis.run(self.func_ir.blocks)
        # reorder statements to maximize fusion
        # push non-parfors down
        maximize_fusion(
            self.func_ir, self.func_ir.blocks, self.typemap, up_direction=False
        )
        dprint_func_ir(self.func_ir, "after maximize fusion down")
        self.fuse_parfors(self.array_analysis, self.func_ir.blocks)
        # push non-parfors up
        maximize_fusion(self.func_ir, self.func_ir.blocks, self.typemap)
        dprint_func_ir(self.func_ir, "after maximize fusion up")
        # try fuse again after maximize
        self.fuse_parfors(self.array_analysis, self.func_ir.blocks)
        dprint_func_ir(self.func_ir, "after fusion")
    # simplify again
    simplify(self.func_ir, self.typemap, self.calltypes)
    # push function call variables inside parfors so gufunc function
    # wouldn't need function variables as argument
    push_call_vars(self.func_ir.blocks, {}, {})
    # simplify again
    simplify(self.func_ir, self.typemap, self.calltypes)
    dprint_func_ir(self.func_ir, "after optimization")
    if config.DEBUG_ARRAY_OPT >= 1:
        print("variable types: ", sorted(self.typemap.items()))
        print("call types: ", self.calltypes)
    # run post processor again to generate Del nodes
    post_proc = postproc.PostProcessor(self.func_ir)
    post_proc.run()
    if self.func_ir.is_generator:
        fix_generator_types(self.func_ir.generator_info, self.return_type, self.typemap)
    if sequential_parfor_lowering:
        lower_parfor_sequential(
            self.typingctx, self.func_ir, self.typemap, self.calltypes
        )
    else:
        # prepare for parallel lowering
        # add parfor params to parfors here since lowering is destructive
        # changing the IR after this is not allowed
        parfor_ids, parfors = get_parfor_params(
            self.func_ir.blocks, self.options.fusion, self.nested_fusion_info
        )
        for p in parfors:
            numba.parfor.get_parfor_reductions(
                self.func_ir, p, p.params, self.calltypes
            )
        if config.DEBUG_ARRAY_OPT_STATS:
            name = self.func_ir.func_id.func_qualname
            n_parfors = len(parfor_ids)
            if n_parfors > 0:
                after_fusion = (
                    "After fusion" if self.options.fusion else "With fusion disabled"
                )
                print(
                    ("{}, function {} has {} parallel for-loop(s) #{}.").format(
                        after_fusion, name, n_parfors, parfor_ids
                    )
                )
            else:
                print("Function {} has no Parfor.".format(name))

    return