我已经包含了主机程序的主要部分,我怀疑这里不正确:
我的指针还不是很好,并且认为我可能错误地分配了一些变量。
这是内核程序,它应该让我知道我的程序正在尝试做什么:
const char *KernelSource = "\n"
"__kernel void sumElements( \n"
" __global float* input, \n"
" __global float output, \n"
" __global int N) \n"
"{ \n"
" int i = get_global_id(0); \n"
" if(i < N) \n"
" output += input[i]; \n"
"} \n"
"\n";
也许这会导致错误,因为我从未尝试过SIMT写入一个变量,如上所述。有可能做这样的事吗?我需要得到数组中所有元素的总和。
答案 0 :(得分:5)
如果您尝试实际读回输出值,则需要将其声明为指针。现在,输出的值被复制为内核参数,但是在内核结束后会忽略对它所做的任何更改。
所以,将__global float output
更改为__global float* output
。然后在你的内核中改变:
if(i < N)
output += input[i];
到
if(i < N)
*output += input[i];
您可能需要更改为此分配缓冲区的方式,但是自从我在OpenCL中完成此操作已经很长时间了,我现在发现的文档并没有显示任何明显的内容缓冲区中的错误。
这里有一个警告:添加不原子操作。通过这种设置,总会发生的是你将有两个或更多线程读取* output的值,然后尝试在不同阶段将* output + 1写入其中。因此,*输出将具有小于它应该的值。
要解决此问题,您需要使用OpenCL atomic operations.