当我尝试使用下面的脚本将数据恢复到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()
答案 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
不需要像为运行代码定义的那样大,但是我将所需的大小作为练习留给读者。 ...