2016-07-31 84 views
6

我想了解@jitclass修飾器如何與嵌套類一起工作。我寫了兩個虛擬類:fifi和toto fifi有一個toto屬性。這兩個類都有@jitclass裝飾器,但是編譯失敗。下面的代碼:如何嵌套numba jitclass

fifi.py

from numba import jitclass, float64 
from toto import toto 

spec = [('a',float64),('b',float64),('c',toto)] 

@jitclass(spec) 
class fifi(object): 
    def __init__(self, combis): 
    self.a = combis 
    self.b = 2 
    self.c = toto(combis) 

    def mySqrt(self,x): 
    s = x 
    for i in xrange(self.a): 
     s = (s + x/s)/2.0 
    return s 

toto.py:

from numba import jitclass,int32 

spec = [('n',int32)] 

@jitclass(spec) 
class toto(object): 
    def __init__(self,n): 
    self.n = 42 + n 

    def work(self,y): 
    return y + self.n 

一個啓動代碼的腳本:

from datetime import datetime 
from fifi import fifi 
from numba import jit 

@jit(nopython = True) 
def run(n,results): 
    for i in xrange(n): 
    q = fifi(200) 
    results[i+1] = q.mySqrt(i + 1) 

if __name__ == '__main__': 
    n = int(1e6) 
    results = [0.0] * (n+1) 
    starttime = datetime.now() 
    run(n,results) 
    endtime = datetime.now() 

    print("Script running time: %s"%str(endtime-starttime)) 
    print("Sqrt of 144 is %f"%results[145]) 

當我運行該腳本,我獲得[...]

TypingError: Untyped global name 'toto' File "fifi.py", line 11

請注意,如果我在'fifi'中刪除了對'toto'的任何引用,代碼就可以正常工作,並且由於numba我得到了x16的加速。

回答

5

可以使用jitclass作爲另一個jitclass的成員,儘管這樣做的方式沒有很好的記錄。您需要使用deferred_type實例。這可以在Numba 0.27以及更早的時候運行。更改fifi.py到:

from numba import jitclass, float64, deferred_type 
from toto import toto 

toto_type = deferred_type() 
toto_type.define(toto.class_type.instance_type) 

spec = [('a',float64),('b',float64),('c',toto_type)] 

@jitclass(spec) 
class fifi(object): 
    def __init__(self, combis): 
    self.a = combis 
    self.b = 2 
    self.c = toto(combis) 

    def mySqrt(self,x): 
    s = x 
    for i in xrange(self.a): 
     s = (s + x/s)/2.0 
    return s 

然後我得到的輸出:

$ python test.py 
Script running time: 0:00:01.991600 
Sqrt of 144 is 12.041595 

此功能可以在一些數據結構的更先進的jitclass例子可以看出,例如: