CL_INVALID_ARG_VALUE 设置缓冲区参数时
CL_INVALID_ARG_VALUE when setting buffer arguments
我正在编写一个 OpenCL 程序,发现我正在读取一个全为零的缓冲区。深入研究英特尔 SDK 跟踪,我发现在设置缓冲区参数时得到 CL_INVALID_ARG_VALUE。 (设置标量参数不会产生错误)
我正在使用 OpenCL C++ 绑定 (cl.hpp)。
由于我的代码很长,我用测试程序复制了这个问题。
cl::CommandQueue queue(context, devices.front());
cl::Buffer resultsBuf(context, CL_MEM_WRITE_ONLY | CL_MEM_HOST_READ_ONLY, sizeof(cl_short) * 2048);
cl::Buffer inputBuf(context, CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(cl_uchar) * 2048, input.data());
queue.enqueueWriteBuffer(inputBuf, CL_TRUE, 0, sizeof(cl_uchar) * 2048, input.data());
// Execution of the following two lines produces CL_INVALID_ARG_VALUE for both.
err = kernel.setArg(0, resultsBuf);
err = kernel.setArg(1, inputBuf);
// Execution of the following line produces CL_INVALID_KERNEL_ARGS
err = queue.enqueueTask(kernel);
vector<cl_short> result(2048);
err = queue.enqueueReadBuffer(resultsBuf, CL_TRUE, 0, sizeof(cl_short) * 2048, result.data());
和内核代码:
__kernel void myKernel(
__local short* resultsBuf,
__local uchar* inputBuf
) {
for (int i = 0; i < 2048; ++i) {
resultsBuf[i] = -3;
}
}
input
是一个 vector<cl_uchar>(2048)
填充了一些测试数据,它还没有用于任何事情。我对这个测试用例的期望是读回一个填充了值 -3 的缓冲区。
我已经将我的代码与我在网上找到的其他示例进行了比较,没有什么让我觉得奇怪的,我已经尝试了各种小调整(比如更改内存标志)但我似乎无法改善情况。
我是否忽略了有关缓冲区的某些内容?
(奇怪的是,我的测试程序确实用一些垃圾字节填充了 result
?)
要在主机和 GPU 之间来回传递数据,您必须使用全局内存。这似乎在主机端完成,但在您的内核中,您使用 __local
内存地址说明符,顾名思义,它是在内核中本地使用的。
固定内核使用 __global
:
__kernel void myKernel(
__global short* resultsBuf,
__global uchar* inputBuf
) {
for (int i = 0; i < 2048; ++i) {
resultsBuf[i] = -3;
}
}
我正在编写一个 OpenCL 程序,发现我正在读取一个全为零的缓冲区。深入研究英特尔 SDK 跟踪,我发现在设置缓冲区参数时得到 CL_INVALID_ARG_VALUE。 (设置标量参数不会产生错误)
我正在使用 OpenCL C++ 绑定 (cl.hpp)。
由于我的代码很长,我用测试程序复制了这个问题。
cl::CommandQueue queue(context, devices.front());
cl::Buffer resultsBuf(context, CL_MEM_WRITE_ONLY | CL_MEM_HOST_READ_ONLY, sizeof(cl_short) * 2048);
cl::Buffer inputBuf(context, CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(cl_uchar) * 2048, input.data());
queue.enqueueWriteBuffer(inputBuf, CL_TRUE, 0, sizeof(cl_uchar) * 2048, input.data());
// Execution of the following two lines produces CL_INVALID_ARG_VALUE for both.
err = kernel.setArg(0, resultsBuf);
err = kernel.setArg(1, inputBuf);
// Execution of the following line produces CL_INVALID_KERNEL_ARGS
err = queue.enqueueTask(kernel);
vector<cl_short> result(2048);
err = queue.enqueueReadBuffer(resultsBuf, CL_TRUE, 0, sizeof(cl_short) * 2048, result.data());
和内核代码:
__kernel void myKernel(
__local short* resultsBuf,
__local uchar* inputBuf
) {
for (int i = 0; i < 2048; ++i) {
resultsBuf[i] = -3;
}
}
input
是一个 vector<cl_uchar>(2048)
填充了一些测试数据,它还没有用于任何事情。我对这个测试用例的期望是读回一个填充了值 -3 的缓冲区。
我已经将我的代码与我在网上找到的其他示例进行了比较,没有什么让我觉得奇怪的,我已经尝试了各种小调整(比如更改内存标志)但我似乎无法改善情况。
我是否忽略了有关缓冲区的某些内容?
(奇怪的是,我的测试程序确实用一些垃圾字节填充了 result
?)
要在主机和 GPU 之间来回传递数据,您必须使用全局内存。这似乎在主机端完成,但在您的内核中,您使用 __local
内存地址说明符,顾名思义,它是在内核中本地使用的。
固定内核使用 __global
:
__kernel void myKernel(
__global short* resultsBuf,
__global uchar* inputBuf
) {
for (int i = 0; i < 2048; ++i) {
resultsBuf[i] = -3;
}
}