为什么我相当琐碎的CUDA程序会因某些争论而错误?

时间:2012-11-01 22:02:30

标签: cuda pycuda

我为练习做了一个简单的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的情况下调用内核时,错误消失了。这是为什么?这个错误意味着什么?

1 个答案:

答案 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)