我是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);
答案 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中相同的工作组(块)和全局维度将您的内核排入队列。