【发布时间】:2018-01-16 06:06:38
【问题描述】:
我目前正在尝试实现 OpenCL 内核。内核应该输出先前计算的元素数除以重新映射为 0 到 255 值的元素总数。
内核在具有 256 个工作项的单个工作组中运行,其中 LX 是本地 ID:
#define LX get_local_id(0)
kernel void reduceStatistic(global int *inout, int nr_workgroups, int nr_pixels)
{
int i = 1;
for (; i < nr_workgroups; i++)
{
inout[LX] += inout[LX + i * 256];
}
inout[LX] = (int)floor(((float)inout[LX] / (float)nr_pixels) * 256.0f);
}
重映射操作之前的计算是为了在同一个缓冲区上一次计算之后进行清理。
清除后的 inout[LX] 的第一项是 17176,nr_pixels 是 160000,因此使用上面的计算结果应该是 27。然而,代码返回 6。
相关主机端代码如下:
// nr_workgroups is of type int
cl_mem outputBuffer = clCreateBuffer(mgr->context, CL_MEM_READ_WRITE, nr_workgroups * 256 * sizeof(cl_int), NULL, NULL);
// another kernel writes into outputBuffer
// set kernel arguments
clSetKernelArg(mgr->reduceStatisticKernel, 0, sizeof(outputBuffer), &outputBuffer);
clSetKernelArg(mgr->reduceStatisticKernel, 1, sizeof(cl_int), &nr_workgroups);
clSetKernelArg(mgr->reduceStatisticKernel, 2, sizeof(cl_int), &imgSeqSize);
size_t global_work_size_statistics[1] = { 256 };
size_t local_work_size_statistics[1] = { 256 };
// run the kernel
clEnqueueNDRangeKernel(mgr->commandQueue, mgr->reduceStatisticKernel, 1, NULL, global_work_size_statistics, local_work_size_statistics, 0, NULL, NULL);
// read result
cl_int *reducedResult = new cl_int[256];
clEnqueueReadBuffer(mgr->commandQueue, outputBuffer, CL_TRUE, 0, 256 * sizeof(cl_int), reducedResult, 0, NULL, NULL);
帮助非常感谢! (:
【问题讨论】:
-
你确定你的意思是
i <= nr_workgroups,不应该是i < nr_workgroups吗?inout[LX + i * 265];中的步幅不应该是 256,而不是 265? -
265 有错,
-
-
您能否检查一下您是否不小心创建了一个乱序队列?只需确保填充缓冲区的内核实际上首先完成。此外,如果您运行 2WG,您将覆盖内存。您可能打算使用 get_global_id()
-
commandQueue = clCreateCommandQueue(context, devices[deviceNo], CL_QUEUE_PROFILING_ENABLE, &status);
标签: opencl