我正在尝试使用python来控制cuda,通过ctypes。在这里,为了说明我的问题,我使用python将指针传递给c函数,这些函数分配cuda内存,将numpy数组复制到cuda mempory,并将cuda内存复制回新的numpy数组。但它似乎没有用,尽管我的基本ctypes设置工作。我认为问题在于从cudaMalloc函数返回到python的内容。
这是python代码
pycu_alloc = dll.alloc_gpu_mem
pycu_alloc.argtypes = [c_size_t]
pycu_alloc.restypes = [c_void_p]
host2gpu = dll.host2gpu
host2gpu.argtypes = [c_void_p, c_void_p, c_size_t]
gpu2host = dll.gpu2host
gpu2host.argtypes = [c_void_p, c_void_p, c_size_t]
a = np.random.randn(1024).astype('float32')
c = np.zeros(1024).astype('float32')
c_a = c_void_p(a.ctypes.data)
c_c = c_void_p(c.ctypes.data)
da = pycu_alloc(1024)
c_da = c_void_p(da)
host2gpu(c_a, c_da, 1024)
gpu2host(c_c, c_da, 1024)
print a
print c
和C:
extern "C" {
float * alloc_gpu_mem( size_t N)
{
float *d;
int size = N *sizeof(float);
int err;
err = cudaMalloc(&d, size);
printf("cuda malloc: %d\n", err);
return d;
}}
extern "C" {
void host2gpu(float * a, void * da, size_t N)
{
int size = N * sizeof(float);
int err;
err = cudaMemcpy(da, a, size, cudaMemcpyHostToDevice);
printf("load mem: %d\n", err);
}}
extern "C"{
void gpu2host(float *c, void *d_c, size_t N)
{
int err;
int size = N*sizeof(float);
err = cudaMemcpy(c, d_c, size, cudaMemcpyDeviceToHost);
printf("cpy mem back %d\n", err);
}}
代码应将随机向量a
复制到cuda内存,然后将该cuda内存复制回空向量c
。当我打印c
时,请注意,它只是0
s。
我已经与float*
和void*
的不同可能性搏斗,特别是alloc_gpu_mem
的工作方式。但我不知道该怎么做。
至于err
返回值,cudaMalloc
会返回0
,但cudaMemcpy
都会返回11。
指针错误的python是什么?救命?
答案 0 :(得分:5)
问题在于:
pycu_alloc.restypes = [c_void_p]
这没有任何作用。你想要的是:
pycu_alloc.restype = c_void_p
请参阅ctypes
文档中的Return types。
如果没有,ctypes
假设您的函数返回C int
。在32位平台上,您可能会使用它,因为您最终会构造一个c_void_p
,其值为int
...但是在64位平台上,该指针最终会结束缺少高32位。
因此,当您将其传递给CUDA时,它会识别出指针不在它知道的任何范围内,并且会返回cudaErrorInvalidValue
(11)。
此外,如果你把一切都搞定了,那么这条线应该是不必要的:
c_da = c_void_p(da)
您正在调用argtypes
指定c_void_p
的函数,因此您可以将int
传递给c_void_p
- 返回函数。< / p>
您可以看到普通旧malloc
和free
的相同行为,但您可能会在free
处获得段错误,而不是一个错误的错误:
malloc = libc.malloc
malloc.argtypes = [c_size_t]
malloc.restype = c_void_p # comment this line to crash on most 64-bit platforms
free = libc.free
free.argtypes = [c_void_p]
free.restype = None
a = malloc(1024)
free(a) # commenting this line and uncommenting the next two has no effect
#c_a = c_void_p(a)
#free(ca)