编辑:意识到我在每次迭代时都在重新实例化 cl_context。现在可以了。
虽然这是一个 JOCL 特定的问题,但我相信它通常适用于 OpenCL。
我有一个程序将 int 数组发送到 OpenCL 内核以在 GPU 上进行处理,然后将结果返回给 Java。该程序在第一次迭代时运行良好,但是当第二次调用 clSetKernelArg(使用新数组)时,它会引发 CL_INVALID_MEM_OBJECT 错误。
我不明白为什么设置内核参数只会在第二次迭代时使程序崩溃。
这是Java代码的简化版本:
... bunch of kernel initialization code that works correctly ...
void doSingleIteration() {
int[] array = new int[length];
fillArrayWithData(array);
cl_mem buf = CL.clCreateBuffer(context, CL.CL_MEM_READ_ONLY,
length * Sizeof.cl_float, null, null);
CL.clEnqueueWriteBuffer(commandQueue, buf, true, 0,
array.length * Sizeof.cl_float, Pointer.to(array), 0, null, null);
CL.clSetKernelArg(kernel, 0, Sizeof.cl_mem, Pointer.to(buf)); // This crashes on the second iteration ONLY??
CL.clEnqueueNDRangeKernel(... this works fine ...)
... some other unrelated code ...
}
doSingleIteration(); // This one is ok
doSingleIteration(); // This one crashes
以下是 OpenCL 中相应内核的标头:
kernel void myKernel(global const int* myArray) {
...
}
我让它工作的唯一方法是在每次迭代时重新实例化命令队列。但这是非常低效的。如何在不使程序崩溃的情况下再次调用 clSetKernelArg?
谢谢