CUDA到OpenCL:OpenCL中的(blockIdx.x + blockIdx.y * gridDim.x)* blockDim.x + threadIdx.x相当于什么?

时间:2017-07-20 01:02:31

标签: cuda opencl

我是OpenCL的初学者,尝试将简单的CUDA函数转换为OpenCL。在CUDA函数中,他们使用下面的代码片段来获取操作索引,

int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x;

get_global_id(0)是否等同于OpenCL中的上述内容?

int id = get_global_id(0);

1 个答案:

答案 0 :(得分:5)

我不熟悉CUDA(仅限OpenCL),但看起来如下:

  • get_group_id(uint dimindx)blockIdx.[xyz]
  • get_local_size(uint dimindx)blockDim.[xyz]
  • get_local_id(uint dimindx)threadIdx.[xyz]
  • get_num_groups(uint dimindx)gridDim.[xyz]

其中dimindx为0,1或2,分别对应.x.y.z

get_global_id(0)get_group_id(0) * get_local_size(0) + get_local_id(0)相同,因此假设上述等价确实正确,则与blockIdx.x * blockDim.x + threadIdx.x相同。 (相当于索引1的.y和索引2的.z)

要获得相同的ID值,我想你可能想要这样的东西:

int id = get_group_id(1) * get_global_size(0) + get_global_id(0);

请注意,原始CUDA代码明确没有考虑threadIdx.y。我怀疑这可能是因为你的blockDim.y是1,或者因为你真的试图进入块中最顶层的项目(而不是与当前线程相对应的那个)。

更常见的情况可能是将当前工作项的索引放入包含2D元素数组的缓冲区中的数组中:

int id = get_global_id(1) * get_global_size(0) + get_global_id(0);

如果get_local_size(1)为1,这当然等同于前面的表达式。(块的高度为1。)

以上所有假设您已经使用与CUDA中相同的工作组(块)和全局维度将您的内核排入队列。