Python: выполнение простой функции на графическом процессоре с помощью Numba. `Недопустимое использование * с параметрами (массив (float64, 1d, C), float64)`

Я пытаюсь получить следующую, совместимую с Numba-nopython, функцию, работающую с target='cuda':

    @numba.jit(nopython = True)
    def hermite_polynomials(X, N):
    r'''
    Evaluate the orthonormal Hermite polynomials on 
    :math:`(\mathbb{R},\frac{1}{\sqrt{2\pi}}\exp(-x^2/2)dx)` in :math:`X\subset\mathbb{R}`


    :param X: Locations of desired evaluations
    :type X:  One dimensional np.array
    :param N: Number of polynomials
    :rtype: numpy.array of shape :code:`X.shape[0] x N`
    '''
    out = np.zeros((X.shape[0], N))
    deg = N - 1
    factorial = np.ones((1,N))
    for i in range(1,N):
        factorial[0,i:]*=i
    orthonormalizer = 1 / np.sqrt(factorial)
    if deg < 1:
        out = np.ones((X.shape[0], 1))
    else:
        out[:, 0] = np.ones((X.shape[0],))      
        out[:, 1] = X
        for n in range(1, deg):
            out[:, n + 1] = X * out[:, n] - n * out[:, n - 1]
    return out * orthonormalizer

Тем не менее, я не нашел ни одного примера кода, который был бы достаточно простым для меня для понимания (только опыт работы с Python и MATLAB, без компьютерного ученого) и достаточно сложным, чтобы действительно быть полезным (я нашел только a+b примеров).

До сих пор я пришел к следующей функции, которой нужно передать массив единиц (сам я не смог определить массив, cuda.local.array((N,1),dtype=float64) выдало ConstantInferenceError). Я согласился с тем, что мне нужно выполнять умножение по записи, следовательно, дополнительные циклы for, но даже это не работает, так как я получаю ошибку Invalid usage of * with parameters (array(float64, 1d, C), float64).

@numba.jit(target = 'cuda')
def hermite_polynomials2(X, N,out):
    r'''
    Evaluate the orthonormal Hermite polynomials on 
    :math:`(\mathbb{R},\frac{1}{\sqrt{2\pi}}\exp(-x^2/2)dx)` in :math:`X\subset\mathbb{R}`


    :param X: Locations of desired evaluations
    :type X:  One dimensional np.array
    :param N: Number of polynomials
    :rtype: numpy.array of shape :code:`X.shape[0] x N`
    '''
    deg = N-1
    L = X.shape[0]
    if deg  == 0:
        return
    else:     
        out[:, 1] = X
        for n in range(1, deg):
            for j in range(L):
                out[j, n + 1] = X * out[j, n] - n * out[j, n - 1]
    factorial = 1
    for i in range(1,N):
        factorial *= i
        for j in range(L):
            out[j,i] /= np.sqrt(factorial)
    return 

Как сделать умножение?


person Bananach    schedule 03.04.2018    source источник
comment
meta.stackoverflow.com/q/284236/681865   -  person talonmies    schedule 03.04.2018
comment
@talonmies я изменил соответствующую строку   -  person Bananach    schedule 03.04.2018


Ответы (1)


Вы, вероятно, хотите что-то вроде:

for j in range(L):
    out[j, n + 1] = X[j] * out[j, n] - n * out[j, n - 1]

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

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

Написанное вами ядро ​​будет полностью последовательным. Это будет медленнее, чем версия CPU. Вам нужно будет написать код совершенно по-другому, чтобы он имел какое-либо значение на графическом процессоре.

person Community    schedule 04.04.2018