为什么 numba 不能使用这个嵌套函数?

Why does numba not work with this nested function?

我在这里报告了所描述的错误:https://github.com/numba/numba/issues/3095,如果有人对问题的解决方案感兴趣的话。

我正在尝试使用 numba 预编译 3D 时间序列数据的最小化 运行。作为第一步,我想定义一个成本函数,但这已经失败了。这是我的代码:

from numba import jit

@jit
def tester(axis,data):
    def lineCost(pars):
        A=pars[0]
        B=pars[1]
        return np.sum((A*axis+B - data)**2)
    return lineCost([axis,data])

tester(1,2)

这会产生 "Not implemented" 错误:

~/.local/lib/python3.5/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)

~/.local/lib/python3.5/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

~/.local/lib/python3.5/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()

~/.local/lib/python3.5/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):

/usr/lib/python3.5/contextlib.py in __exit__(self, type, value, traceback)
     75                 value = type()
     76             try:
---> 77                 self.gen.throw(type, value, traceback)
     78                 raise RuntimeError("generator didn't stop after throw()")
     79             except StopIteration as exc:

~/.local/lib/python3.5/site-packages/numba/errors.py in new_error_context(fmt_, *args, **kwargs)
    583         from numba import config
    584         tb = sys.exc_info()[2] if config.FULL_TRACEBACKS else None
--> 585         six.reraise(type(newerr), newerr, tb)
    586
    587

~/.local/lib/python3.5/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 at object (object mode backend)
make_function(closure=[=11=].3, defaults=None, name=$const0.5, code=<code object lineCost at 0x7fd7ada3b810, file "<ipython-input-59-ef6835d3b147>", line 3>)

File "<ipython-input-59-ef6835d3b147>", line 3:
def tester(axis,data):
    def lineCost(pars):
    ^
[1] During: lowering "[=11=].6 = make_function(closure=[=11=].3, defaults=None, name=$const0.5, code=<code object lineCost at 0x7fd7ada3b810, file "<ipython-input-59-ef6835d3b147>", line 3>)" at <ipython-input-59-ef6835d3b147> (3)
-------------------------------------------------------------------------------
This should not have happened, a problem has occurred in Numba's internals.

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!

你能帮我理解代码的哪一部分导致了 numba 的问题吗?那将是非常大的帮助。谢谢!

最好的, 马尔特

避免全局变量(数据和轴在lineCost中是全局的),避免包含函数的函数和避免列表([轴,数据])。

工作示例

from numba import jit

@jit
def lineCost(axis,data):
    return np.sum((axis*axis+data - data)**2)

@jit
def tester(axis,data):
    return lineCost(axis,data)

tester(1,2)

大多数这些东西应该在最新版本中工作,但不推荐使用经常包含一些错误或一些不受支持的细节的最新功能。

即使这可行,如果性能低于预期,我也不会感到惊讶。

实际上,这似乎是一个在最新版本中被删除的错误:) https://github.com/numba/numba/issues/3095