Функция устройства выдает исключение nopython при возврате списка вместо целого числа - PullRequest
0 голосов
/ 04 июля 2018

функция устройства, которую я написал, всегда вызывает исключение без python, и я не понимаю, почему или где моя ошибка.

Вот небольшой пример, который представляет мою проблему. У меня есть следующая функция устройства, которую я вызываю из ядра:

@cuda.jit (device=True)
def sub_stuff(vec_a, vec_b):
    x0 = vec_a[0] - vec_b[0]
    x1 = vec_a[1] - vec_b[1]
    x2 = vec_a[2] - vec_b[2]
    return [x0, x1, x2]

Ядро, которое вызывает эту функцию, выглядит так:

@cuda.jit
def kernel_via_polygon(vectors_a, vectors_b, result_array):
    pos = cuda.grid(1)
    if pos < vectors_a.size and pos < result_array.size:
        result_array[pos] = sub_stuff(vectors_a[pos], vectors_b[pos])

Три входных массива следующие:

vectors_a = np.arange(1, 10).reshape((3, 3))
vectors_b = np.arange(1, 10).reshape((3, 3))
result = np.zeros_like(vectors_a)

Когда я теперь вызываю функцию через trace_via_polygon (vectors_a, vectors_b, result) ошибка python не возникает. Когда функция устройства возвращает только целое значение, эта ошибка предотвращается. Может кто-нибудь объяснить мне, где моя ошибка?

Редактировать: К вашему сведению Построение списка талонов не поддерживается в коде устройства. Альтернатива, которая мне помогла, - это использование кортежей, которые поддерживаются.

1 Ответ

0 голосов
/ 06 июля 2018

Источником вашей ошибки является то, что функция устройства sub_stuff пытается создать список в коде графического процессора, и это не поддерживается.

О лучшем, что вы можете сделать, было бы что-то вроде этого:

from numba import jit, guvectorize, int32, int64, float64
from numba import cuda
import numpy as np
import math

@cuda.jit (device=True)
def sub_stuff(vec_a, vec_b, result):
    for i in range(vec_a.shape[0]):
        result[i] = vec_a[i] - vec_b[i]

@cuda.jit
def kernel_via_polygon(vectors_a, vectors_b, result_array):
    pos = cuda.grid(1)
    if pos < vectors_a.size and pos < result_array.size:
         sub_stuff(vectors_a[pos], vectors_b[pos], result_array[pos])

vectors_a = 100 + np.arange(1, 10).reshape((3, 3))
vectors_b = np.arange(1, 10).reshape((3, 3))
result = np.zeros_like(vectors_a)

kernel_via_polygon[1,10](vectors_a, vectors_b, result)

print(result)

, который использует цикл для итерации отдельных срезов массива и выполнения вычитания между каждым элементом.

...