【发布时间】:2018-12-06 17:31:18
【问题描述】:
我正在测试 OpenCL 2.0 缩减内核以获得 2d-workgroups 的最大值。
我打电话:
//get global max
float max_v;
max_v = work_group_reduce_max(hsv_fi.z);
if(get_local_id(0) == 0 && get_local_id(1) == 0){
result[get_group_id(0)] = 1337;// max_v;
}
在我的内核末尾。 1337 用于测试目的。我期望一个包含 1337 个值的 workgroupsize 数组。
但我不知何故只得到一个值。我在内核中有什么明显的错误吗?
我尝试通过以下方式阅读:
int errcode;
float* resultData = (float*)oclEnvironment._commandQueue.enqueueMapBuffer(resultBuffer, true, CL_MAP_READ, 0, size, 0, 0, &errcode);
std::copy((float*)resultData, (float*)(resultData + size), (float*)dest);
我的 *dest 指针是:
std::vector<float> resultArray;
我保留了工作组大小,并通过以下方式将指针交给它 (*dest):
resultArray.data()
有什么建议吗?我觉得我错过了一些小事。
谢谢!
编辑:
cl::NDRange global(width, height);
//Intel HD 530 can have a max. workgroup size of 256.
int dim1 = 16;
int dim2 = 16;
cl::NDRange local(dim1, dim2);
//Calculate the number of workgroups
int numberOfWorkgroups = ceil((width * height) / (float)(dim1 * dim2));
//each workgroup reduces the data to a single element. This elements are then reduced on host in the final reduction step.
oclEnvironment._commandQueue.enqueueNDRangeKernel(_kernel, cl::NullRange, global, local);
edit2:
我还是不明白 OpenCL 在做什么。我有一个 480x360 的图像,我希望它作为每个元素 3 个字节(rgb)的缓冲区。我现在在列表中得到了 30 个有效的最大值,但不是我怀疑的 675 个。图像的分辨率为 480 * 360。我的最大工作组大小为 (16,16,1)。所以我得到了我认为的 675 个工作组。不知何故,我只收到了 30 个值,其他的都是零。我试图将输入填充到 480*368 以使两个维度都是 16 的倍数。仍然相同。如果这 30 个值减少了我的整个数据集并且我收到的该列表的最大值是最大值,那就没问题了。但由于我不确定发生了什么,我不能确定是这样。
【问题讨论】:
-
应该不是问题,但是
(float*)中的额外std::copy转换有什么用? -
size是字节大小还是浮点数?用法似乎不一致。 -
(float*) 确实没有必要。我可以删除它们,但对我的问题没有任何影响。大小是浮点数或工作组数。
-
我怀疑
enqueueMapBuffer的大小是字节数,而不是项目数。 -
我用 size * sizeof(float) 试过了,但它崩溃了。