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

Avi*_*vis 2 cuda opencl

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

int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x;
Run Code Online (Sandbox Code Playgroud)

在getCL中,get_global_id(0)是否等同于上述内容?

int id = get_global_id(0);
Run Code Online (Sandbox Code Playgroud)

pmd*_*mdj 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);
Run Code Online (Sandbox Code Playgroud)

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

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

int id = get_global_id(1) * get_global_size(0) + get_global_id(0);
Run Code Online (Sandbox Code Playgroud)

如果get_local_size(1)是1,这当然等于前面的表达式.(块具有高度1.)

以上所有假设您已经将您的内核与CUDA中的等效工作组(块)和全局维度排列在一起.