2016-07-31 22 views
6

Tôi đang cố gắng hiểu cách trình trang trí @jitclass hoạt động với các lớp lồng nhau. Tôi đã viết hai lớp giả: fifi và toto fifi có thuộc tính toto. Cả hai lớp đều có trang trí @jitclass nhưng việc biên dịch không thành công. Dưới đây là các mã:Cách làm tổ 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 

Các kịch bản mà ra mắt mã:

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]) 

Khi tôi chạy kịch bản, tôi nhận được [...]

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

Lưu ý rằng nếu tôi xóa bất kỳ tham chiếu nào đến 'toto' trong 'fifi', mã hoạt động tốt và tôi nhận được tốc độ x16 lên nhờ vào tê giác.

Trả lời

5

Có thể sử dụng một jitclass làm thành viên của một lớp jitclass khác, mặc dù cách thực hiện điều này không được ghi chép đầy đủ. Bạn cần sử dụng phiên bản deferred_type. Điều này hoạt động ở Numba 0.27 và có thể sớm hơn. Thay đổi fifi.py tới:

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 

sau đó tôi nhận được như đầu ra:

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

Chức năng này có thể được nhìn thấy trong một số ví dụ jitclass tiên tiến hơn của cấu trúc dữ liệu, ví dụ: