numba / numba

NumPy aware dynamic Python compiler using LLVM
https://numba.pydata.org/
BSD 2-Clause "Simplified" License
9.87k stars 1.12k forks source link

Lower Error when creating numpy array #3709

Open ngharrison opened 5 years ago

ngharrison commented 5 years ago

I am creating a 2D numpy array with a mix of ints and floats:

import numpy as np
from numba import jit

@njit
def fj():
    return np.array([[1, 2.1],[0,1]])

fj()

It fails with the following errors:

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
~\Anaconda3\lib\site-packages\numba\errors.py in new_error_context(fmt_, *args, **kwargs)
    598     try:
--> 599         yield
    600     except NumbaError as e:

~\Anaconda3\lib\site-packages\numba\lowering.py in lower_block(self, block)
    253                                    loc=self.loc, errcls_=defaulterrcls):
--> 254                 self.lower_inst(inst)
    255 

~\Anaconda3\lib\site-packages\numba\lowering.py in lower_inst(self, inst)
    302             ty = self.typeof(inst.target.name)
--> 303             val = self.lower_assign(ty, inst)
    304             self.storevar(val, inst.target.name)

~\Anaconda3\lib\site-packages\numba\lowering.py in lower_assign(self, ty, inst)
    448         elif isinstance(value, ir.Expr):
--> 449             return self.lower_expr(ty, value)
    450 

~\Anaconda3\lib\site-packages\numba\lowering.py in lower_expr(self, resty, expr)
    993             castvals = [self.context.cast(self.builder, val, fromty, resty.dtype)
--> 994                         for val, fromty in zip(itemvals, itemtys)]
    995             return self.context.build_list(self.builder, resty, castvals)

~\Anaconda3\lib\site-packages\numba\lowering.py in <listcomp>(.0)
    993             castvals = [self.context.cast(self.builder, val, fromty, resty.dtype)
--> 994                         for val, fromty in zip(itemvals, itemtys)]
    995             return self.context.build_list(self.builder, resty, castvals)

~\Anaconda3\lib\site-packages\numba\targets\base.py in cast(self, builder, val, fromty, toty)
    676             impl = self._casts.find((fromty, toty))
--> 677             return impl(self, builder, fromty, toty, val)
    678         except NotImplementedError:

~\Anaconda3\lib\site-packages\numba\targets\listobj.py in list_to_list(context, builder, fromty, toty, val)
   1089     # Casting from non-reflected to reflected
-> 1090     assert fromty.dtype == toty.dtype
   1091     return val

AssertionError: 

During handling of the above exception, another exception occurred:

LoweringError                             Traceback (most recent call last)
<ipython-input-30-d0de78b978b7> in <module>()
----> 1 fj()

~\Anaconda3\lib\site-packages\numba\dispatcher.py in _compile_for_args(self, *args, **kws)
    365                     e.patch_message(''.join(e.args) + help_msg)
    366             # ignore the FULL_TRACEBACKS config, this needs reporting!
--> 367             raise e
    368 
    369     def inspect_llvm(self, signature=None):

~\Anaconda3\lib\site-packages\numba\dispatcher.py in _compile_for_args(self, *args, **kws)
    322                 argtypes.append(self.typeof_pyval(a))
    323         try:
--> 324             return self.compile(tuple(argtypes))
    325         except errors.TypingError as e:
    326             # Intercept typing error that may be due to an argument

~\Anaconda3\lib\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 

~\Anaconda3\lib\site-packages\numba\dispatcher.py in compile(self, sig)
    653 
    654             self._cache_misses[sig] += 1
--> 655             cres = self._compiler.compile(args, return_type)
    656             self.add_overload(cres)
    657             self._cache.save_overload(sig, cres)

~\Anaconda3\lib\site-packages\numba\dispatcher.py in compile(self, args, return_type)
     80                                       args=args, return_type=return_type,
     81                                       flags=flags, locals=self.locals,
---> 82                                       pipeline_class=self.pipeline_class)
     83         # Check typing error if object mode is used
     84         if cres.typing_error is not None and not flags.enable_pyobject:

~\Anaconda3\lib\site-packages\numba\compiler.py in compile_extra(typingctx, targetctx, func, args, return_type, flags, locals, library, pipeline_class)
    902     pipeline = pipeline_class(typingctx, targetctx, library,
    903                               args, return_type, flags, locals)
--> 904     return pipeline.compile_extra(func)
    905 
    906 

~\Anaconda3\lib\site-packages\numba\compiler.py in compile_extra(self, func)
    365         self.lifted = ()
    366         self.lifted_from = None
--> 367         return self._compile_bytecode()
    368 
    369     def compile_ir(self, func_ir, lifted=(), lifted_from=None):

~\Anaconda3\lib\site-packages\numba\compiler.py in _compile_bytecode(self)
    833         """
    834         assert self.func_ir is None
--> 835         return self._compile_core()
    836 
    837     def _compile_ir(self):

~\Anaconda3\lib\site-packages\numba\compiler.py in _compile_core(self)
    820         self.define_pipelines(pm)
    821         pm.finalize()
--> 822         res = pm.run(self.status)
    823         if res is not None:
    824             # Early pipeline completion

~\Anaconda3\lib\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 

~\Anaconda3\lib\site-packages\numba\compiler.py in run(self, status)
    251                     # No more fallback pipelines?
    252                     if is_final_pipeline:
--> 253                         raise patched_exception
    254                     # Go to next fallback pipeline
    255                     else:

~\Anaconda3\lib\site-packages\numba\compiler.py in run(self, status)
    242                 try:
    243                     event(stage_name)
--> 244                     stage()
    245                 except _EarlyPipelineCompletion as e:
    246                     return e.result

~\Anaconda3\lib\site-packages\numba\compiler.py in stage_nopython_backend(self)
    694         """
    695         lowerfn = self.backend_nopython_mode
--> 696         self._backend(lowerfn, objectmode=False)
    697 
    698     def stage_compile_interp_mode(self):

~\Anaconda3\lib\site-packages\numba\compiler.py in _backend(self, lowerfn, objectmode)
    644             self.library.enable_object_caching()
    645 
--> 646         lowered = lowerfn()
    647         signature = typing.signature(self.return_type, *self.args)
    648         self.cr = compile_result(

~\Anaconda3\lib\site-packages\numba\compiler.py in backend_nopython_mode(self)
    631                 self.return_type,
    632                 self.calltypes,
--> 633                 self.flags)
    634 
    635     def _backend(self, lowerfn, objectmode):

~\Anaconda3\lib\site-packages\numba\compiler.py in native_lowering_stage(targetctx, library, interp, typemap, restype, calltypes, flags)
   1021 
   1022     lower = lowering.Lower(targetctx, library, fndesc, interp)
-> 1023     lower.lower()
   1024     if not flags.no_cpython_wrapper:
   1025         lower.create_cpython_wrapper(flags.release_gil)

~\Anaconda3\lib\site-packages\numba\lowering.py in lower(self)
    171         if self.generator_info is None:
    172             self.genlower = None
--> 173             self.lower_normal_function(self.fndesc)
    174         else:
    175             self.genlower = self.GeneratorLower(self)

~\Anaconda3\lib\site-packages\numba\lowering.py in lower_normal_function(self, fndesc)
    212         # Init argument values
    213         self.extract_function_arguments()
--> 214         entry_block_tail = self.lower_function_body()
    215 
    216         # Close tail of entry block

~\Anaconda3\lib\site-packages\numba\lowering.py in lower_function_body(self)
    237             bb = self.blkmap[offset]
    238             self.builder.position_at_end(bb)
--> 239             self.lower_block(block)
    240 
    241         self.post_lower()

~\Anaconda3\lib\site-packages\numba\lowering.py in lower_block(self, block)
    252             with new_error_context('lowering "{inst}" at {loc}', inst=inst,
    253                                    loc=self.loc, errcls_=defaulterrcls):
--> 254                 self.lower_inst(inst)
    255 
    256     def create_cpython_wrapper(self, release_gil=False):

~\Anaconda3\lib\contextlib.py in __exit__(self, type, value, traceback)
     97                 value = type()
     98             try:
---> 99                 self.gen.throw(type, value, traceback)
    100             except StopIteration as exc:
    101                 # Suppress StopIteration *unless* it's the same exception that

~\Anaconda3\lib\site-packages\numba\errors.py in new_error_context(fmt_, *args, **kwargs)
    605         from numba import config
    606         tb = sys.exc_info()[2] if config.FULL_TRACEBACKS else None
--> 607         six.reraise(type(newerr), newerr, tb)
    608 
    609 

~\Anaconda3\lib\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-29-a5afb679cd70>", line 3:
def fj():
    return np.array([[1, 2.1],[0,1]])
    ^

[1] During: lowering "$0.9 = build_list(items=[Var($0.5, <ipython-input-29-a5afb679cd70> (3)), Var($0.8, <ipython-input-29-a5afb679cd70> (3))])" at <ipython-input-29-a5afb679cd70> (3)
-------------------------------------------------------------------------------
This should not have happened, a problem has occurred in Numba's internals.

If I explicitly supply the dtype, the same errors occur:

@njit
def fj():
    return np.array([[1, 2.1],[0,1]], dtype=np.float64)

It works fine if at least one element in each sub-list is a float:

@njit
def fj():
    return np.array([[1, 2.1],[0.,1]])

I expect this isn't the desired behavior.

stuartarchibald commented 5 years ago

note: edited report with markdown syntax.

stuartarchibald commented 5 years ago

Thanks for the report, I can reproduce. I think this is because the outer list is typed by the first declared inner list, i.e. first inner list is a list(float64) which makes the outer list list(list(float64)), however the second declared inner list is typed as a list(int64). The problem occurs when generating the LLVM code as the assumption of homogeneous nested list types is broken by the list(int64) inferred type, hence assertion error.

Minimal reproducer:

import numpy as np
from numba import njit

@njit
def f():
    return [[1, 2.1], [0, 1]]

print(f())
koshMer commented 2 years ago

I encountered the same problem today. I guess my only option is to create a 1-D array and reshaping it?

esc commented 2 years ago

I encountered the same problem today. I guess my only option is to create a 1-D array and reshaping it?

I think so. Either that or using at least one float values in all nested lists?