CUDA 到 OpenCL:OpenCL 中 (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x 的等效项是什么?

CUDA to OpenCL : What is the equivalent of (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x in 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);

我不熟悉 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 相同。 (对于带 .y 的索引 1 和带 .z 的索引 2 等效)

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

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

请注意,原始 CUDA 代码明确没有考虑 threadIdx.y。我怀疑这可能是因为您的 blockDim.y 是 1,或者因为您确实在尝试获取块中的最顶层项目(而不是与当前线程对应的项目)。

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

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

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

以上所有内容均假定您已使用与 CUDA 中相同的工作组(块)和全局维度对内核进行排队。