PyCUDA奇怪的错误cuLaunchKernel失败:值无效

时间:2014-01-04 19:53:18

标签: python cuda pycuda

当我尝试使用下面的脚本将数据恢复到cpu时,出现错误。 当我尝试在“ref”中添加一些值时,如果我只是放入:

,我不会收到错误
ref[1] = 255; ref[0] = 255; ref[2] = 255;

但如果我这样做:

if (verschil.a[idx+idy*640]>5){
  ref[1] = 255; ref[0] = 255; ref[2] = 255;
}

我得到的错误信息是:

Traceback (most recent call last):
File "./zwartwit.py", line 159, in <module>
verwerking(cuda.InOut(refe),cuda.InOut(frame), block=(640, 1, 1))
File "/usr/lib/python2.7/dist-packages/pycuda/driver.py", line 374, in function_call
func._launch_kernel(grid, block, arg_buf, shared, None)
pycuda._driver.LogicError: cuLaunchKernel failed: invalid value

感谢您的帮助!

ps,这是我正在讨论的脚本的简化版本。为了得到同样的错误,必须删除//。

import pycuda.driver as cuda
import pycuda.autoinit
from pycuda.compiler import SourceModule
import numpy
import cv2
from time import time,sleep

mod = SourceModule("""
struct legear{ int a[307200];};
__global__ void totaal(int *ref){ 
  int idx = threadIdx.x + blockIdx.x *  blockDim.x;
  legear test;
  for (int idy=0;idy<480;idy++){
    if (idy < 480){
      if (idx < 640){
    if (ref[idx*3+idy*640*3]>100){
      test.a[idx+idy*640] = 255;
    }
    //if (test.a[idx+idy*640] == 255){
      ref[idx*3+idy*640*3] = 255; ref[idx*3+idy*640*3+1] = 255; ref[idx*3+idy*640*3+2] = 255; 
    //}
      }
    }
  }
  }
""")

camera = cv2.VideoCapture(0)
im2 = numpy.zeros((768, 1024, 1 ),dtype=numpy.uint8)
cv2.imshow("projector", im2)
key = cv2.waitKey(100)
for i in range(0,8):
  refe = camera.read()[1]
im2[500:502] = [100]
cv2.imshow("projector", im2)
key = cv2.waitKey(100)
verwerking = mod.get_function("totaal")
refe = refe.astype(numpy.int32)
verwerking(cuda.InOut(refe), block=(640, 1, 1))
refe = refe.astype(numpy.uint8)
cv2.imshow("test", refe)
cv2.waitKey(200)
raw_input()

1 个答案:

答案 0 :(得分:2)

这里的基本问题是内核中test的大小。正如您所写,每个线程需要1228800字节的本地内存。运行时必须为每个线程保留该内存 - 因此您的代码需要750Mb的可用内存来分配设备上的本地内存,以支持您尝试启动的每个块的640个线程。我的猜测是你的设备没有那么多的可用内存。

你所展示的代码在没有if语句的情况下工作的原因归结为编译器优化 - 在这种情况下test实际上并没有用于任何事情,编译器只是将其从代码中删除,这消除了内核的巨大本地内存占用并允许它运行。取消注释if语句时,test确定全局内存写入的状态,因此编译器无法对其进行优化,内核需要运行大量本地内存。

这是我发布时使用内核代码看到的编译器输出:

> nvcc -arch=sm_21 -Xptxas="-v" -m32 -c wnkr_py.cu
wnkr_py.cu
wnkr_py.cu(7): warning: variable "test" was set but never used

tmpxft_00000394_00000000-5_wnkr_py.cudafe1.gpu
tmpxft_00000394_00000000-10_wnkr_py.cudafe2.gpu
wnkr_py.cu
wnkr_py.cu(7): warning: variable "test" was set but never used

ptxas : info : 0 bytes gmem
ptxas : info : Compiling entry function '_Z6totaalPi' for 'sm_21'
ptxas : info : Function properties for _Z6totaalPi
    0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas : info : Used 8 registers, 36 bytes cmem[0], 4 bytes cmem[16]
tmpxft_00000394_00000000-5_wnkr_py.cudafe1.cpp
tmpxft_00000394_00000000-15_wnkr_py.ii

请注意编译器警告和堆栈帧大小。

if语句处于活动状态:

>nvcc -arch=sm_21 -Xptxas="-v" -m32 -c wnkr_py.cu
wnkr_py.cu
tmpxft_000017c8_00000000-5_wnkr_py.cudafe1.gpu
tmpxft_000017c8_00000000-10_wnkr_py.cudafe2.gpu
wnkr_py.cu
ptxas : info : 0 bytes gmem
ptxas : info : Compiling entry function '_Z6totaalPi' for 'sm_21'
ptxas : info : Function properties for _Z6totaalPi
    1228800 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas : info : Used 7 registers, 36 bytes cmem[0]
tmpxft_000017c8_00000000-5_wnkr_py.cudafe1.cpp
tmpxft_000017c8_00000000-15_wnkr_py.ii

请注意,堆栈帧大小更改为每个线程1228800个字节。

我快速阅读代码表明,test不需要像为运行代码定义的那样大,但是我将所需的大小作为练习留给读者。 ...