我正在使用 Numba(版本 0.37.0)来优化 GPU 代码。我想使用组合矢量化函数(使用 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 的其他方法有什么建议吗?