OpenCL。数组寻址/指针的奇怪错误

OpenCL。数组寻址/指针的奇怪错误,c,linux,arrays,pointers,opencl,C,Linux,Arrays,Pointers,Opencl,我有这个简单的内核用于测试 __kernel void nfa(__global const int *a, __global int *output) { output[0] = a[0]; } 注意:这是在cpu上运行的,内存可能在主机上。它导致了这个错误 *检测到glibc/program:malloc():smallbin双链接列表已损坏:0x0000000000a4a540** 我怀疑这会破坏程序的一部分,因为它正在访问主机内存。但据我所知,所有的内存分配都是正确的。

我有这个简单的内核用于测试

__kernel void nfa(__global const int *a, __global int *output)
{
        output[0] = a[0];
}
注意:这是在cpu上运行的,内存可能在主机上。它导致了这个错误

*检测到glibc/program:malloc():smallbin双链接列表已损坏:0x0000000000a4a540**

我怀疑这会破坏程序的一部分,因为它正在访问主机内存。但据我所知,所有的内存分配都是正确的。它位于堆栈上,但在运行时保持在范围内

但是,如果我这样做:

   __kernel void nfa(__global const int *a, __global int *output)
    {
            a = a;
            output[0] = a[0];
    }
结果是答案2,这是正确的,因为a是一个带有[2,4,8]的数组

一个分配给它自己修复的问题

这也很好,结果是4

   __kernel void nfa(__global const int *a, __global int *output)
    {
            output[0] = a[1];
    }
似乎只是访问[0],而没有分配给其自身会导致问题

有人知道发生了什么事吗

我在linux上使用AMD OpenCL驱动程序(使用intel CPU,但我有AMD卡)

编辑:

创建缓冲区时使用的代码(压缩,数组和缓冲区之间还有其他代码):

我可能错了(我没有使用C++ opcl,但我相信它和C绑定大致相同),但是我相信:

调用cl::Buffer的参数的最后一种类型是void*。您需要的是一个指向正在传递的内存块的指针,在本例中是数组(由于数组的原因,它会自动转换为指针)。您已经传入了一个指向数组的指针(即指向指针的指针),编译器会悄悄地将其转换为void*。这意味着,您将复制数组指针,然后在内存中复制2个整数。我可以想象这会导致糟糕的结果

我不确定为什么a=a或output=a[1]会修复它,因为我没有CPU OpenCL的经验,我也不确定具体的工作原理。在GPU上,您可以解释为设备出于性能原因而缓存内存,从而防止内存失效(或其他原因)


编辑:哎呀,刚刚意识到这有多老了,我应该学会更好地阅读

你是用malloc还是用clCreateBuffer()分配内存的?我相信后者是必需的,即使你在CPU设备上,内存在堆栈上。使用CulCuraButter(相当于我使用C++绑定),CelCeCuffSuffic方法通过指向数组的指针,它使用标志“CLMyMyUsHoestPoT Pt”。据我所知,这可能导致直接使用内存,并将其复制到GPU。因为我没有使用GPU,它在主机上。我们可以看到您的clSetKernelArg()调用吗?为什么不使用CL_MEM_COPY_host_PTR进行测试?我的意思是,我不明白你是如何确保OpenCL在函数返回后不访问数组的?
int a[3];
a[0] = 2;
a[1] = 4;
a[2] = 8;

cl::Buffer bufferA = cl::Buffer(context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR , sizeof(int) * 3, &a);