GPU のコードを最適化するために Numba (バージョン 0.37.0) を使用しています。ベクトル化された関数を組み合わせて使用したい (Numba の @vectorize デコレータを使用)。
インポートとデータ:
import numpy as np
from math import sqrt
from numba import vectorize, guvectorize
angles = np.random.uniform(-np.pi, np.pi, 10)
coords = np.stack([np.cos(angles), np.sin(angles)], axis=1)
これは期待どおりに機能します。
@guvectorize(['(float32[:], float32[:])'], '(i)->()', target='cuda')
def l2_norm(vec, out):
acc = 0.0
for value in vec:
acc += value**2
out[0] = sqrt(acc)
l2_norm(coords)
出力:
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], dtype=float32)
しかし、別のベクトル化された関数を呼び出して、「l2_norm」内でその「for」を使用することは避けたいと思います。
私はこれを試しました:
@vectorize(["float32(float32)"], target="cuda")
def power(value):
return value**2
@guvectorize(['(float32[:], float32[:])'], '(i)->()', target='cuda')
def l2_norm_power(vec, out):
acc = 0.0
acc = power(vec)
acc = acc.sum()
out[0] = sqrt(acc)
l2_norm_power(coords)
ただし、TypingError が発生します。
TypingError: Failed at nopython (nopython frontend)
Untyped global name 'power': cannot determine Numba type of <class
'numba.cuda.dispatcher.CUDAUFuncDispatcher'>
この組み合わせを実行する方法について何か考えはありますか?
Numba で l2_norm を最適化する他の方法について何か提案はありますか?