То, как я использую pycuda, и то, как я думаю, что оно предназначено для использования, является мостовым интерфейсом между python и cuda.Это не инструмент интерфейса Python-> C ++.Для этого вам нужно посмотреть на что-то вроде SWIG .Я бы не использовал pycuda в коде c ++ для взаимодействия с графическим процессором, вместо этого я бы прототипировал или проектировал свое приложение, используя pycuda, а позже перешел бы на использование только c ++.
Имея это в виду, я постараюсь ответить на ваши вопросы
1) С Pycuda вы также можете использовать модуль gpuarray, который будет выполнять шаги выделения и передачи для вас, так что вы можете простосоздайте их и используйте в графическом процессоре:
import pycuda.gpuarray as gpuarray
a = gpuarray.arange(400, dtype=numpy.float32)
b = gpuarray.arange(400, dtype=numpy.float32)
#call Cuda function pass 'a' and 'b'
resulta = a.get()
resultb = b.get()
2) Опять же, pycuda не является интерфейсом c ++. Если вам нужны результаты для перехода из cuda-> python-> c ++, я не думаю,вам нужен питон посередине.
3) Да, блок (4,4,1) - 16 потоков, а сетка (16,16) - 256 блоков.
Редактировать:
Чтобы ответить на некоторые ваши комментарии:
Да, блок (4,1,1) является одномерным, а блок (4,4,1) -2D.
Я исправил ваш код, вам просто нужно было передать N ядру CUDA.
import pycuda.driver as cuda
import pycuda.autoinit
from pycuda.compiler import SourceModule
import scipy as sc
N=50*1024
a=sc.arange(0,N).astype(sc.float32)
a_gpu = cuda.mem_alloc(a.nbytes) #allocate memory on GPU
cuda.memcpy_htod(a_gpu, a) #transfer data to the GPU
b=sc.array([i**2 for i in range(0,N)]).astype(sc.float32)
b_gpu = cuda.mem_alloc(b.nbytes)#allocate memory on GPU
cuda.memcpy_htod(b_gpu, b) #transfer data to the GPU
c=sc.zeros(N).astype(sc.float32)
c_gpu = cuda.mem_alloc(c.nbytes)#allocate memory on GPU
mod = SourceModule("""
__global__ void add(int*a,int *b,int *c, int N){
int tid=threadIdx.x + blockIdx.x*gridDim.x;
while (tid<N){
c[tid]=a[tid]+b[tid];
tid+=blockDim.x*gridDim.x;
}
}
""")
#call the function(kernel)
func = mod.get_function("add")
func(a_gpu,b_gpu,c_gpu, sc.int32(N), block=(16,16,1),grid=(16,16))
#transfer data back to CPU
cuda.memcpy_dtoh(c, c_gpu)
print c
Еще один способ сделать это - использовать подстановку строк в SourceModule:
mod = SourceModule("""
__global__ void add(int*a,int *b,int *c){
const int N = %d;
int tid=threadIdx.x + blockIdx.x*gridDim.x;
while (tid<N){
c[tid]=a[tid]+b[tid];
tid+=blockDim.x*gridDim.x;
}
}
""" % (N))
Последнее замечание: при использовании Pycuda он обычно работает как клей.это объединяет все разные части совместной работы с CUDA.Это поможет вам скомпилировать выделенную память, запустить ядро и т. Д. До тех пор, пока вы используете это, у вас все будет хорошо.