2017-11-10 3 views
2

次のコードはnumbaを使用したリンクリストの実装です(関連する例はherehereおよびhereです)。 remove関数は、位置indexの要素を削除します。 (indexは常に有効な位置になるものとします) このような要素(index)を削除するには、element[index-1].next -> element[index+1]のような割り当てを行います。それは、次のエラーとラインprev.next = cur.nextで破っリンクリスト要素の '次の'リンクを再割り当てするときの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() 

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はそのようにしていないようですここで何が起こっているのか確かめてください。

私はnumba 0.35.0python 3.6.2を使用しています。

アイデア?

ありがとうございました。


現状

エラーがNumbaのバグです。詳細については、対応する問題を参照してください。https://github.com/numba/numba/issues/2606

答えて

1

この機能は、nopythonのように見えます。 「通常の」jitデコレータを使用してください。必要であれば、これは、プレーンのPythonにフォールバック:jit(nopython=True)と同等です

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ので。

テスト出力:

10 
0 
+0

は、それはあなたfoは動作しますか? –

+0

実行します。しかし、実際には純粋なPython(@jitなし)よりも遅いです。あなたが 'timeit'をしていると、装飾されたバージョン@jitは〜180usで、純粋なpythonは〜80usで動作します。 – Brandt

+0

私にとってPyPyのユースケースに似ています。 –

関連する問題