I need to be able to call a GPU function which itself calls another GPU function indirectly:
from numba import cuda, jit
import numpy as np
# GPU function
@cuda.jit(device = True)
def euclidean_distance_gpu(input_vec, weight, diffs):
i = cuda.grid(1)
if i < input_vec.shape[0]:
diffs[i] = (input_vec[i] - weight[i]) ** 2
@jit
# CPU function
def euclidean_distance_cpu(diffs):
diffs_sum = np.sum(diffs)
euclidean_distance = np.sqrt(diffs_sum)
return euclidean_distance
@jit
# CPU function
def euclidean_distance(input_vec, weight):
euclidean_distance_gpu[1, 5](input_vec, weight, diffs)
return euclidean_distance_cpu(diffs)
@cuda.jit
# GPU function
def compare(input_vec, categories, diffs):
i = cuda.grid(1)
if i < categories.shape[0]:
euclidean_dist = 0
euclidean_dist = euclidean_distance(input_vec, categories[i])
diffs[i] = euclidean_dist
vec1 = np.array([1, 2, 3, 4, 5])
c1 = np.array([2, 3, 4, 5, 6])
c2 = np.array([3, 4, 5, 6, 7])
c = np.array([c1, c2])
diffs = np.array([0, 0])
compare(vec1, c, diffs)
In this case, I need to call the compare() function, which itself calls euclidean_distance_gpu() through euclidean_distance(), and compare() and euclidean_distance_gpu() are functions meant to use a GPU.
From what I understand, both functions need to be decorated with @cuda.jit, with euclidean_distance_gpu() being decorated with @cuda.jit(device = True). However, when I call compare() later on, I don't see how this can be called without raising an error, since it first has to go through a CPU function (euclidean_distance() decorated with @jit).
My understanding is that you can only call a cuda.jit function from another cuda.jit function - is this correct? Let's say I made euclidean_distance() into a cuda.jit function as well. Is there a way to make this work correctly, through all those layers of function calls?
I'm quite new to jit - is there anything I can do here? Note these functions are actually more complex than shown so I'd like an actual solution rather than just in-lining the function.