Numba 開發手冊 (二)


四、靈活專業的@generated_jit

@jit修飾符在很多情況下是極其有效的,但是有時需要根據輸入變量的類型來決定函數的實現功能。@generated_jit修飾符編譯時能夠進行一些特例化選擇。

示例:

import numpy as np

from numba import generated_jit, types

@generated_jit(nopython=True)
def is_missing(x):
    """
    Return True if the value is missing, False otherwise.
    """
    if isinstance(x, types.Float):
        return lambda x: np.isnan(x)
    elif isinstance(x, (types.NPDatetime, types.NPTimedelta)):
        # The corresponding Not-a-Time value
        missing = x('NaT')
        return lambda x: x == missing
    else:
        return lambda x: False

上面的代碼完成的是根據輸入去判斷缺省值的事情。

注意下面問題:

1、在調用的時候,傳入的參數,使用變量的numba類型,而不是值;

2、這個修飾函數返回的結果不是一個計算結果;

 

五、創建Numpy通用函數(universal funtions)

首先 看下什么叫做universal funtions:

A universal function (or ufunc for short) is a function that operates on ndarrays in an element-by-element fashion, supporting array broadcasting, type casting, and several other standard features. That is, a ufunc is a “vectorized” wrapper for a function that takes a fixed number of specific inputs and produces a fixed number of specific outputs.

@vectorize修飾符

傳統的ufuncs的構建是涉及到C語言編程的,numba中只需要@vectorize修飾符,就可以獲得和C寫的ufuncs一樣快速的性能。

使用@vectorize,可以寫操作輸入標量的函數,而不是arrays。(這是什么意思?)

(這個地方給出的示例沒有看懂,除了定義的時候不同,沒有看出有什么區別)

按照文檔里面的說法,是NumPy ufuncs會自動獲得其他功能,如縮小,累積或廣播。

@guvectorize修飾符

guvectorize允許處理任意長度的輸入arrays。

但是與vectorize不同的是,guvectorize不會返回結果值,而是作為函數的參數傳入。

下面是一個示例:

 

@guvectorize([(int64[:], int64, int64[:])], '(n),()->(n)')
def g(x, y, res):
    for i in range(x.shape[0]):
        res[i] = x[i] + y

 

上面的函數中,傳入的是一個一維數組和一個標量,最后一個傳入的參數是結果值。在聲明的過程中,有兩個事情需要注意一下:

  • '(n),()->(n)'的意思是說明傳入的是一個長度維n的一維向量和一個標量,輸出的是一個長度為n的一維向量
  •  需要指定支持的數據類型

Dynamic universal functions

 

如果不去申明具體的數據類型,那么將會編譯出一個dynamic universal function。

每次改變傳入的數據類型,那么numba就會generate新的kernels。

 

六、用@jitclass編譯python類

示例:

 

import numpy as np
from numba import jitclass          # import the decorator
from numba import int32, float32    # import the types

spec = [
    ('value', int32),               # a simple scalar field
    ('array', float32[:]),          # an array field
]

@jitclass(spec)
class Bag(object):
    def __init__(self, value):
        self.value = value
        self.array = np.zeros(value, dtype=np.float32)

    @property
    def size(self):
        return self.array.size

    def increment(self, val):
        for i in range(self.size):
            self.array[i] = val
        return self.array

 

(此處留坑)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM