Вызов функции __device__ с использованием PyCUDA возвращает ошибку

Когда я пытаюсь запустить следующий код, я получаю эту ошибку:

Traceback (most recent call last):
  File "C:\temp\GPU Program Shell.py", line 28, in <module>
    dev=mod.get_function("lol")
  File "C:\Python33\lib\site-packages\pycuda\compiler.py", line 285, in get_function
    return self.module.get_function(name)
pycuda._driver.LogicError: cuModuleGetFunction failed: not found

Вот код:

mod = SourceModule("""

extern "C" {
__device__ void lol(double *a)
{
    a[0]=1;
}


__global__ void kernel(double *a)
{
    const int r = blockIdx.x*blockDim.x + threadIdx.x;
    a[r] = 1;
}
}
""")

max_length = 5
a = numpy.zeros(max_length)
a_gpu = cuda.mem_alloc(a.nbytes)
cuda.memcpy_htod(a_gpu, a)
func = mod.get_function("kernel")
dev=mod.get_function("lol")
dev(a_gpu)
newa = numpy.empty_like(a)
cuda.memcpy_dtoh(newa, a_gpu)

print(newa)
print(a)

Как вы, вероятно, видите, это небольшая модификация кода учебника PyCUDA. Я намерен назвать эту функцию устройства, которая будет запускать ядра и интегрировать вещи, и в целом сделает мою жизнь проще. Я немного погуглил, и я знал, что мне пришлось поместить «extern «c»» в свой код из-за искажения имен, и у меня уже был успех с этим раньше, когда я просто использовал PyCUDA для запуска ядра вместо функции устройства. В том же духе, если я изменю свой код для запуска ядра вместо функции устройства, он будет делать то, что я хочу. Что мне здесь не хватает?

Карстен

Еще немного заглянув в документацию по интерфейсу устройства, и кажется, что функция get_function работает только с глобальными функциями? Я правильно это интерпретировал? Если да, то могу ли я делать то, что пытаюсь сделать?


person Hair of Slytherin    schedule 14.10.2013    source источник


Ответы (1)


Вы не можете вызвать функцию __device__ из кода хоста. Если вы указываете, что код учебника PyCUDA показывает, как это сделать, я хотел бы увидеть этот учебник.

Мне непонятно, чего вы пытаетесь добиться, вызывая функцию __device__ из кода хоста, что невозможно сделать с помощью обычного запуска ядра (__global__).

person Robert Crovella    schedule 15.10.2013
comment
Верно, Роберт, я понял, что это был глупый вопрос вскоре после того, как задал его. Что я пытаюсь сделать, так это написать интегратор, который работает исключительно на графическом процессоре после того, как я отправлю ему начальные условия и параметры. Я хотел, чтобы функция устройства (для которой я сейчас использую однопоточное ядро) запускала интегратор и могла вызывать другие ядра для выполнения интеграции. - person Hair of Slytherin; 15.10.2013
comment
Вы можете запустить ядро ​​__global__ всего с одним блоком одного потока, который должен вести себя так же, как функция __device__, которую вы имеете в виду. Не пытаюсь комментировать общую идею, только механику. - person Robert Crovella; 15.10.2013
comment
Да, это то, что я пытаюсь сделать прямо сейчас. Как вы думаете, это плохая идея? - person Hair of Slytherin; 15.10.2013
comment
Обычно запуск ядра из одного блока и одного потока — это не то, как вы получаете производительность от графического процессора. Но ваше описание (я намерен назвать эту функцию устройства, которая будет запускать ядра и интегрировать вещи) звучит как своего рода главный поток, что может быть в порядке. В этом вопросе недостаточно информации, чтобы прокомментировать его более конкретно. - person Robert Crovella; 15.10.2013