我为练习做了一个简单的CUDA程序。它只是将数据从一个数组复制到另一个数组:
import pycuda.driver as cuda
import pycuda.autoinit
import numpy as np
from pycuda.compiler import SourceModule
# Global constants
N = 2**20 # size of array a
a = np.linspace(0, 1, N)
e = np.empty_like(a)
block_size_x = 512
# Instantiate block and grid sizes.
block_size = (block_size_x, 1, 1)
grid_size = (N / block_size_x, 1)
# Create the CUDA kernel, and run it.
mod = SourceModule("""
__global__ void D2x_kernel(double* a, double* e, int N) {
int tid = blockDim.x * blockIdx.x + threadIdx.x;
if (tid > 0 && tid < N - 1) {
e[tid] = a[tid];
}
}
""")
func = mod.get_function('D2x_kernel')
func(a, cuda.InOut(e), np.int32(N), block=block_size, grid=grid_size)
print str(e)
但是,我收到此错误:pycuda._driver.LogicError: cuLaunchKernel failed: invalid value
当我在我的内核函数中删除第二个参数double* e
并在没有参数e
的情况下调用内核时,错误消失了。这是为什么?这个错误意味着什么?
答案 0 :(得分:2)
你的a
数组在设备内存中不存在,所以我怀疑PyCUDA忽略(或以其他方式处理)内核调用的第一个参数,只传入e
和{{1} } ...所以你得到一个错误,因为内核期望三个参数,它只收到两个。从内核定义中删除N
可能会消除您收到的错误消息,但您的内核仍然无法正常工作。
快速解决此问题的方法是将double* e
包裹在a
调用中,该调用指示PyCUDA在启动内核之前将cuda.In()
复制到设备。也就是说,你的内核启动线应该是:
a
编辑:另外,您是否意识到您的内核没有将func(cuda.In(a), cuda.InOut(e), np.int32(N), block=block_size, grid=grid_size)
的第一个和最后一个元素复制到a
?您的e
声明阻止了这一点。对于整个数组,它应该是if (tid > 0 && tid < N - 1)
。