我对OpenCL非常环保。我试图在英特尔的网站上获取样本,但我不能。 This is the sample。
我在尝试将整数参数传递给clSetKernelArg时收到错误CL_INVALID_MEM_OBJECT,如下所示:
err = clSetKernelArg(ocl->kernel, 2, sizeof(cl_mem), (void *)&width);
if (CL_SUCCESS != err)
{
LogError("Error: Failed to set argument dstMem, returned %s\n", TranslateOpenCLError(err));
return err;
}
本教程应该适用于图像,并且具体说明参数应该如下设置:
err |= clSetKernelArg(ocl->kernel, 2, sizeof(cl_mem), (void *) &width);
err |= clSetKernelArg(ocl->kernel, 3, sizeof(cl_mem), (void *) &height);
这是完整的功能:
cl_uint SetKernelArguments(ocl_args_d_t *ocl, cl_uint width, cl_uint height)
{
cl_int err = CL_SUCCESS;
err = clSetKernelArg(ocl->kernel, 0, sizeof(cl_mem), (void *)&ocl->srcA);
if (CL_SUCCESS != err)
{
LogError("error: Failed to set argument srcA, returned %s\n", TranslateOpenCLError(err));
return err;
}
err = clSetKernelArg(ocl->kernel, 1, sizeof(cl_mem), (void *)&ocl->dstMem);
if (CL_SUCCESS != err)
{
LogError("Error: Failed to set argument dstMem, returned %s\n", TranslateOpenCLError(err));
return err;
}
err = clSetKernelArg(ocl->kernel, 2, sizeof(cl_uint), (void *)&width);
if (CL_SUCCESS != err)
{
LogError("Error: Failed to set argument dstMem, returned %s\n", TranslateOpenCLError(err));
return err;
}
err = clSetKernelArg(ocl->kernel, 3, sizeof(cl_mem), (void *)&height);
if (CL_SUCCESS != err)
{
LogError("Error: Failed to set argument dstMem, returned %s\n", TranslateOpenCLError(err));
return err;
}
return err;
}
最后一个注释:将clSetKernelArg的大小更改为sizeof(cl_uint)会将错误更改为CL_INVALID_ARG_SIZE。
如果这还不够,我会在github here上公开来源。
很确定我在教程中遵循了说明,但我无法弄清楚我可能错过了什么。谢谢你的时间。
答案 0 :(得分:1)
我在github上快速浏览了你的代码,我想我可以给你一些建议。
首先,在使用“cl_mem”类型的内存对象之前调用“clCreateBuffer”,换句话说,在调用之前确保“width”的类型为“cl_mem”
cl_mem cl_width = clCreateBuffer(context,CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR,
sizeof(width), &width,*err);
err = clSetKernelArg(ocl->kernel, 2, sizeof(cl_mem), &cl_width);
我不确定它是否会奏效。
其次,根据我的经验,使用“cl_mem”来传递诸如“int”或“char”之类的值是折旧的。如果我是你,我将省略“clCreateBuffer”子句并编写如下代码:
cl_int width = doSomeThingYouWant();
err = clSetKernelArg(ocl->kernel, 2, sizeof(cl_uint), &width);
希望它有所帮助。
答案 1 :(得分:1)
让我试着简要回答你的问题。
如果我们看一下clSetKernelArg函数的定义:
cl_int clSetKernelArg ( cl_kernel kernel,
cl_uint arg_index,
size_t arg_size,
const void *arg_value)
你可以看到,你需要传递给clSetKernelArg的是指向你的参数的指针,以及参数的大小。现在,您的参数只是一个普通的cl_uint变量。因此,我们可以有以下几点:
const void *arg_value -> &width
size_t arg_size -> sizeof(width)
因此,您的API调用将是这样的:
err |= clSetKernelArg(ocl->kernel, 2, sizeof(width), (void *) &width);
err |= clSetKernelArg(ocl->kernel, 3, sizeof(height), (void *) &height);