I'm using Numba (version 0.37.0) to optimize code for GPU. I would like to use combined vectorized functions (using @vectorize decorator of Numba).
Imports & Data:
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)
This works as expected:
@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)
Output:
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], dtype=float32)
But I'd like to avoid using that "for" inside "l2_norm" by calling another vectorized function.
I've tried this:
@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)
But raises TypingError:
TypingError: Failed at nopython (nopython frontend)
Untyped global name 'power': cannot determine Numba type of <class
'numba.cuda.dispatcher.CUDAUFuncDispatcher'>
Any idea about how to perform this combination?
Any suggestion about other way to optimize l2_norm with Numba?