【问题标题】:How to pass array in kernel, do something and then return it - OpenCL如何在内核中传递数组,做一些事情然后返回它 - OpenCL
【发布时间】:2013-12-23 20:39:25
【问题描述】:

我正在尝试将数组传递给 OpenCL 内核,然后对其进行处理并将其传递回主机。我已经修改了这个tutorial中的代码。

这只是用于确定 OpenCL 实际工作方式的内核。我希望这只是从array1的第一个元素中减去2并将其存储到array2的第一个元素中:

__kernel void test(global int* array1, global int* array2) {
    array2[0] = array1[0] - 2;
}

在 main 我有两个数组,一个(host1)有一些数字,第二个(host2)初始化为零。 比创建我使用的内存缓冲区:

memobj = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, MEM_SIZE * sizeof(int), &host1, &ret);
memobj2 = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, MEM_SIZE * sizeof(int), &host2, &ret);

构建程序后我设置参数:

ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), &host1);
ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), &host2);

然后在执行后我尝试取回该数组。

ret = clEnqueueReadBuffer(command_queue, memobj2, CL_TRUE, 0, MEM_SIZE * sizeof(int), host2, 0, NULL, NULL);

如果我将 memobj2 更改为 memobj,host2 将包含 host1 的值,否则保持不变。我猜这不是返回数组的方式。

我被困在这一点上。

【问题讨论】:

  • 如何执行内核?您应该给它一个 1x1x1 的本地和全局工作大小。另外:您是否检查每一个返回值是否存在错误?
  • @leemes 喜欢教程中的ret = clEnqueueTask(command_queue, kernel, 0, NULL,NULL);
  • 好吧,这实际上相当于clEnqueueNDRangeKernel,范围为我所说的 1x1x1。现在关于错误,你检查它们吗?
  • 每个cl* 函数都会返回一个错误代码(或几乎每个)。你应该检查这个错误。你的教程没有,那很糟糕。您可以将this 之类的内容添加到您的项目中,并将每个 cl 调用包装在某个函数 void check(cl_int e) { if (e) { throw std::runtime_error(get_error_string(e)); } } 或类似函数中;所以你所有的电话看起来像check(clCreateBuffer(...));
  • 我猜是__global,而不是global

标签: c++ opencl


【解决方案1】:

您对clSetKernelArg() 的调用无效 - 您应该传递 OpenCL 缓冲区,而不是主机指针。例如:

ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memobj);
ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), &memobj2);

正如已经指出的,您应该检查每个 OpenCL 运行时 API 调用的返回码。这会很快将您指向错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-09
    • 2019-11-01
    • 2011-08-11
    • 1970-01-01
    • 2021-12-31
    相关资源
    最近更新 更多