Как использовать функцию подготовки из PyCUDA

У меня проблемы с передачей правильных параметров функции prepare (и к подготовленному_вызову) на выделение общей памяти в PyCUDA. Я так понимаю сообщение об ошибке, что одна из переменных, которые я передаю в PyCUDA, представляет собой long вместо того, что я предполагал float32. Но я не вижу, откуда берется переменная.

Кроме того, мне кажется, что официальный пример и < href="http://documen.tician.de/pycuda/driver.html?highlight=prepare#pycuda.driver.Function.prepare" rel="nofollow noreferrer">документация prepare противоречит друг другу в отношении если block должно быть None или нет.

from pycuda import driver, compiler, gpuarray, tools
import pycuda.autoinit
import numpy as np

kernel_code ="""
__device__ void loadVector(float *target, float* source, int dimensions )
{
    for( int i = 0; i < dimensions; i++ ) target[i] = source[i];
}
__global__ void kernel(float* data, int dimensions, float* debug)
{
    extern __shared__ float mean[];
    if(threadIdx.x == 0) loadVector( mean, &data[0], dimensions );
    debug[threadIdx.x]=  mean[threadIdx.x];
}
"""

dimensions = 12
np.random.seed(23)
data = np.random.randn(dimensions).astype(np.float32)
data_gpu = gpuarray.to_gpu(data)
debug = gpuarray.zeros(dimensions, dtype=np.float32)

mod = compiler.SourceModule(kernel_code)
kernel = mod.get_function("kernel")
kernel.prepare("PiP",block = (dimensions, 1, 1),shared=data.size)
grid = (1,1)
kernel.prepared_call(grid,data_gpu,dimensions,debug)
print debug.get()

Вывод

Traceback (most recent call last):
File "shared_memory_minimal_example.py", line 28, in <module>
kernel.prepared_call(grid,data_gpu,dimensions,debug)
File "/usr/local/lib/python2.6/dist-packages/pycuda-0.94.2-py2.6-linux-x86_64.egg/pycuda/driver.py", line 230, in function_prepared_call
func.param_setv(0, pack(func.arg_format, *args))
pycuda._pvt_struct.error: cannot convert argument to long

person Framester    schedule 05.08.2011    source источник
comment
возможный дубликат Создать массивы в общей памяти без шаблонов как в PyOpenCL   -  person talonmies    schedule 05.08.2011
comment
Я дал вам ответ, который объясняет, как это сделать: еще один вопрос, который вы разместили около месяца назад.   -  person talonmies    schedule 05.08.2011
comment
Обновите вопрос, включив в него новый код и информацию.   -  person talonmies    schedule 05.08.2011
comment
Привет Talonmies, я обновил весь вопрос. Спасибо за ваших пациентов.   -  person Framester    schedule 05.08.2011


Ответы (1)


Я столкнулся с этой же проблемой, и мне потребовалось некоторое время, чтобы найти ответ, так что вот. Причиной сообщения об ошибке является то, что data_gpu является экземпляром GPUArray, т.е. вы сделали его с помощью

data_gpu = gpuarray.to_gpu(data)

Чтобы передать его в prepare_call, вам нужно выполнить data_gpu.gpudata, чтобы получить связанное DeviceAllocation instance (т.е. фактически указатель на место в памяти устройства).

Кроме того, передача аргумента блока для подготовки теперь устарела, поэтому правильный вызов будет что-то вроде этого:

data_gpu = gpuarray.to_gpu(data)
func.prepare( "P" )
grid = (1,1)
block = (1,1,1)
func.prepared_call( grid, block, data_gpu.gpudata )
person James Thorniley    schedule 30.05.2013