Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
nopython模式下Numba的递归函数出错_Python_Python 3.x_Recursion_Tuples_Numba - Fatal编程技术网

nopython模式下Numba的递归函数出错

nopython模式下Numba的递归函数出错,python,python-3.x,recursion,tuples,numba,Python,Python 3.x,Recursion,Tuples,Numba,我想在Numba中运行一个递归函数,使用nopython模式。到现在为止,我只会犯错误。这是一个非常简单的代码,用户给出一个少于五个元素的元组,然后函数创建另一个元组,并在元组中添加一个新值(在本例中为数字3)。重复此操作,直到最后一个元组的长度为5。由于某种原因,这不起作用,不知道为什么 @njit def tup(a): 如果len(a)==5: 归还 其他: b=a+(3,) b=tup(b) 返回b 例如,如果a=(0,1),我希望最终结果是tuple(0,1,3,3) 编辑:我使用的

我想在Numba中运行一个递归函数,使用nopython模式。到现在为止,我只会犯错误。这是一个非常简单的代码,用户给出一个少于五个元素的元组,然后函数创建另一个元组,并在元组中添加一个新值(在本例中为数字3)。重复此操作,直到最后一个元组的长度为5。由于某种原因,这不起作用,不知道为什么

@njit
def tup(a):
如果len(a)==5:
归还
其他:
b=a+(3,)
b=tup(b)
返回b
例如,如果
a=(0,1)
,我希望最终结果是tuple
(0,1,3,3)

编辑:我使用的是Numba 0.41.0,我得到的错误是内核正在死亡,“内核似乎已经死亡。”。它将自动重新启动。

根据当前版本:

numba中的递归支持目前仅限于使用 函数的显式类型注释。这个限制来自于 无法确定递归调用的返回类型

因此,不妨尝试:

from numba import jit

@jit()
def tup(a:tuple) -> tuple:
    if len(a) == 5:
        return a

    return tup(a + (3,))

print(tup((0, 1)))

看看这是否对你有好处。

你不应该这么做有几个原因:

  • 这通常是一种在纯Python中可能比在numba修饰函数中更快的方法
  • 迭代将更简单,可能更快,但是要注意,连元组通常是一个
    O(n)
    操作,即使在numba中也是如此。因此,该函数的总体性能将是
    O(n**2)
    。这可以通过使用支持
    O(1)
    附录的数据结构或支持预分配大小的数据结构来改进。或者干脆不使用“循环”或“递归”方法
  • 您是否尝试过如果省略
    njit
    decorator并传入包含6个元素的元组会发生什么情况?(提示:它将达到递归限制,因为它永远不会满足递归的结束条件)
在编写0.43.1时,Numba只支持在递归之间参数类型不变的简单递归。在您的情况下,类型确实发生了变化,您传入了一个
元组(int64 x 2)
,但是递归调用尝试传入一个不同类型的
元组(int64 x 3)
。奇怪的是,它在我的电脑上遇到了一个
StackOverflow
,这看起来像是numba中的一个bug

我的建议是使用这个(无numba,无递归):


请不要忘记显示您会遇到什么样的错误。包括numba版本也可能有帮助,因为numba仍在积极开发中,并且支持的功能集正在快速发展。运行它时,这真的有效吗?我只是试着运行代码,至少是在我的机器上,它只会产生堆栈溢出。你的numba版本是什么?@MSeifert,我刚刚访问了numba网站和他们的“在线试用”jupyter页面。在那里,有注释对我很有效,但没有注释就不行。我所知道的都很有趣谢谢你的解释。但是它在nopython模式下也会失败。非常感谢你的回答。事实上,这段代码并不完全是我想要运行的,它只是我试图做的有问题的部分。最初的问题是在多维数组的条目上运行任意嵌套循环。由于循环的数量可能不同,我在进行递归调用,每个调用进入下一个循环,并相应地构造(多)索引。如果我只传递具有最终大小的元组,一切都会变得更简单,我可以在开始循环之前知道它的大小,问题是元组是不可变的,所以我不能将索引的值赋给它们。我可以使用数组而不是元组,并且可以分配新值,但我不能使用索引数组,比如[1,2,0,0,1]来访问多维M的值M[1,2,0,0,1]。numba也不允许我将数组转换为元组。。。我也找不出一个列表解决方案…似乎每种方法都有一些细节阻止我去做我想做的事情。无论如何,我已经看到纯python在递归方面实际上比numba更快,正如你所说的。这有点令人失望,我希望获得性能,因为numba对循环的性能更好。@Integral不是每个循环都可以用numba进行优化,它实际上取决于您在循环内执行的操作。@Integral numba中数组-元组转换的问题是因为元组需要有一个固定的编译时大小。数组没有那个大小(列表也没有),所以不能从数组创建元组。我还发现在numba中使用多维数组和自定义索引相当复杂。
def tup(a):
    if len(a) < 5:
        a += (3, ) * (5 - len(a))
    return a
>>> tup((1,))
(1, 3, 3, 3, 3)
>>> tup((1, 2))
(1, 2, 3, 3, 3)