1

我做了一个简单的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,错误就消失了。这是为什么?这个错误是什么意思?

4

1 回答 1

2

您的a数组在设备内存中不存在,因此我怀疑 PyCUDA 忽略(或以其他方式处理)您的内核调用的第一个参数,并且只传入eand N...所以您收到错误,因为内核需要三个参数并且它只收到了两个。从内核定义中删除double* e可能会消除您收到的错误消息,但您的内核仍然无法正常工作。

对此的快速修复应该是封装a一个cuda.In()调用,该调用指示 PyCUDAa在启动内核之前复制到设备。也就是说,您的内核启动行应该是:

func(cuda.In(a), cuda.InOut(e), np.int32(N), block=block_size, grid=grid_size)

编辑:另外,您是否意识到您的内核没有复制ato的第一个和最后一个元素e?你的if (tid > 0 && tid < N - 1)声明正在阻止这种情况。对于整个数组,它应该是if (tid < N).

于 2012-11-02T17:13:08.567 回答