以下代码是我使用numba实现的链接列表(可以看到相关示例here,here和here)。
remove
函数删除位置index
处的元素。
(请注意,这里假设index
始终是有效位置)
要删除此类元素(index
),我们会执行element[index-1].next -> element[index+1]
之类的分配。但是当我这样做时,numba似乎并不喜欢:
from numba import deferred_type,optional
from numba import int64
from numba import jitclass,njit
list_type = deferred_type()
spec = [
('data',int64),
('next',optional(list_type))
]
@jitclass(spec)
class List(object):
def __init__(self,data,next):
self.data = data
self.next = next
def prepend(self, data):
return List(data, self)
list_type.define(List.class_type.instance_type)
def length(stack):
i = 0
while stack is not None:
stack = stack.next
i+=1
return i
@njit
def remove(stack,index):
prev = None
if index == 0:
stack = stack.next
else:
cur = stack
i = 0
while cur is not None:
if index == i:
break
i = i+1
prev = cur
cur = cur.next
prev.next = cur.next
return stack
def runme():
from numpy.random import randint
a = randint(0,100,10)
list_ = None
for n in a:
if list_ is None:
list_ = List(n,None)
else:
list_ = list_.prepend(n)
print(length(list_))
indexes = list(range(len(a)))
for i in indexes[::-1]:
list_ = remove(list_,i)
print(length(list_))
if __name__ == '__main__':
runme()
它在第prev.next = cur.next
行中断,出现以下错误:
numba.errors.LoweringError: Failed at nopython (nopython mode backend)
No definition for lowering ?instance.jitclass.List#14bebc8<data:int64,next:?DeferredType#140432587762264>.next = ?DeferredType#140432587762264
File "numba_test.py", line 43
[1] During: lowering "(prev).next = $70.2" at numba_test.py (43)
看起来prev.next
无法重新分配,但我不确定这里发生了什么。
我正在使用 numba 0.35.0 和 python 3.6.2 。
有什么想法吗?
感谢。
当前状态
错误是Numba中的错误。有关详细信息,请转到相应的问题:https://github.com/numba/numba/issues/2606
答案 0 :(得分:1)
看起来nopython
模式确实支持此功能。只需使用“普通”jit
装饰器即可。如果需要,这可以回到普通的Python:
from numba import jit
@jit
def remove(stack,index):
prev = None
if index == 0:
stack = stack.next
else:
cur = stack
i = 0
while cur is not None:
if index == i:
break
i = i+1
prev = cur
cur = cur.next
prev.next = cur.next
return stack
因为njit
等同于jit(nopython=True)
。
测试输出:
10
0