2017-08-07 34 views
0

我写在OpenCL程序,并已发现我在看所有零的缓冲器出来的时候。潜入英特尔SDK跟踪中,我发现在设置缓冲区参数时我获得了CL_INVALID_ARG_VALUE。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的缓冲区。

我比较我与我在网上找到其他样本代码,并没有跳出我奇怪,我已经试过各种小调整(如改变MEM标志)和我似乎无法改善情况。

有件事情我已经忽略了有关缓冲区?

(好奇我的测试程序并填写result有一些垃圾字节?)

回答

3

主机和您必须使用全局内存GPU之间一个来回传递数据。这似乎在主机端完成,但在内核中,您使用内存地址说明符,其名称暗示将在内核中本地使用。 固定内核使用__global

__kernel void myKernel(
    __global short* resultsBuf, 
    __global uchar* inputBuf 
) { 
    for (int i = 0; i < 2048; ++i) { 
     resultsBuf[i] = -3; 
    } 
} 
+0

感谢。我真的以为我有这个选择。 – braks

+0

你知道,如果我设置内核参数传递给__private我得到的错误:“指针参数到内核函数必须驻留在‘__global’,‘__constant’或'__local的地址空间”。这似乎暗示它可能可以使用__local? – braks

+0

看来,对于inputBuf我可以使__constant没有问题。我想有不同的情况。这里有更多关于__local的内容:https://stackoverflow.com/questions/30249801/passing-arguments-through-local-memory-in-opencl – braks